码迷,mamicode.com
首页 > 其他好文 > 详细

HDU4782 Beautiful Soup

时间:2014-05-08 00:47:37      阅读:417      评论:0      收藏:0      [点我收藏+]

标签: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

HDU4782 Beautiful Soup

标签:blog   class   code   ext   color   int   

原文地址:http://www.cnblogs.com/chanme/p/3714776.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!