标签:blog class code ext color int
成都赛里的一道坑爹码力题,突然间脑抽想做一下弥补一下当时的遗憾。当时没做出这道题一是因为当时只剩大概45分钟,对于这样的具有各种条件的题无从下手,二则是因为当时估算着已经有银牌了,所以就不挣扎了。但是像这种题还是一定要敲一下的。
这学期学了编译原理,知道了一些在编译上处理这种题目的一些姿势,例如自动机,parse tree什么的,所以写起来就会更清晰。其实说白了本题的难点在于tokenizer,就是将里面有意义的部分全部弄出来,归结起来可以看成4种,分别是opentag,closetag,blanktag,string,根据有无<>以及/的位置就可以确定下是属于哪一种。然后题目最麻烦的其实就正如它文末的那句,“You quickly realize that your only job is to deal with the white spaces.”
吃空格可以用下面的一句while解决 while((c=getchar)&&isSpace(c)); 这样就可以得到第一个不是空格的字符,然后就是不停的吃后面的字符,当吃到空格或者是<的时候就表示到了一个分隔符,前面的字符串就可以先弄出来了。注意的是‘<’会作为下一个token的第一个字符,所以要加个save表示是否存起来。
tokenizer的机理大概是这样的。 首先要得到下一个token的第一个字符,如果save==true,表示已经有了,否则利用while((c=getchar)&&isSpace(c))吃出第一个非空字符。根据第一个字符类型判断是string还是tag,如果是tag就不停地吃直到吃到的字符是‘>‘,如果是string,就不停的吃吃到第一个分隔符。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 |
#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string> #include <cstdio> using
namespace std; #define maxn 1000000 #define INIT 0 #define OPENTAG 1 #define CLOSETAG 2 #define BLANKTAG 3 #define STRING 4 #define END 5 char
token[maxn]; int
cur; int
tokenType; int
lastType; int
indent; bool
save; char
savechar; bool
isSpace( char
c){ return
c == ‘ ‘ || c == ‘ ‘
|| c == ‘\n‘ ; } bool
isdel( char
c){ return
c == ‘ ‘ || c == ‘ ‘
|| c == ‘\n‘
|| c == ‘<‘ ; } void
printSpace() { for
( int i = 0; i < indent; i++){ putchar ( ‘ ‘ ); } } void
nextToken() { char
c; cur = 0; if
(save){ c = savechar; token[cur++] = c; save = false ; } else { while
((c = getchar ()) && isSpace(c)); token[cur++] = c; } if
(token[0] == ‘<‘ ){ while
((c = getchar ())&&c!= ‘>‘ ){ token[cur++] = c; } token[cur++] = c; if
(token[cur - 2] == ‘/‘ ) tokenType = BLANKTAG; else
if (token[1] == ‘/‘ ) tokenType = CLOSETAG; else
tokenType = OPENTAG; token[cur++] = ‘\0‘ ; return ; } else { while
((c = getchar ()) && !isdel(c)){ token[cur++] = c; } if
(c == ‘<‘ ){ save = true ; savechar = ‘<‘ ; } token[cur++] = ‘\0‘ ; tokenType = STRING; } } int
main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int
T; cin >> T; int
ca = 0; bool
endcase = false ; indent = 0; lastType = INIT; save = false ; while
(1) { if
(!endcase) { printf ( "Case #%d:\n" , ++ca); endcase = true ; } nextToken(); if
(tokenType == OPENTAG){ if
(lastType == STRING) puts ( "" ); printSpace(); printf ( "%s\n" , token); ++indent; } else
if (tokenType == CLOSETAG){ if
(lastType == STRING) puts ( "" ); --indent; printSpace(); printf ( "%s\n" , token); } else
if (tokenType == BLANKTAG){ if
(lastType == STRING) puts ( "" ); printSpace(); printf ( "%s\n" , token); } else { if
(lastType == STRING) putchar ( ‘ ‘ ); else
{ printSpace(); } printf ( "%s" , token); } if
( strcmp (token, "</html>" ) == 0){ endcase = false ; lastType = INIT; indent = 0; if
(ca == T){ break ; } } lastType = tokenType; } return
0; } |
HDU4782 Beautiful Soup,布布扣,bubuko.com
标签:blog class code ext color int
原文地址:http://www.cnblogs.com/chanme/p/3714776.html