成都赛里的一道坑爹码力题,突然间脑抽想做一下弥补一下当时的遗憾。当时没做出这道题一是因为当时只剩大概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,就不停的吃吃到第一个分隔符。

#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的更多相关文章

  1. hdu4782 Beautiful Soup (模拟)

    http://acm.hdu.edu.cn/showproblem.php?pid=4782 2013成都区域赛全题PDF:http://acm.hdu.edu.cn/downloads/2013Ch ...

  2. 使用Beautiful Soup编写一个爬虫 系列随笔汇总

    这几篇博文只是为了记录学习Beautiful Soup的过程,不仅方便自己以后查看,也许能帮到同样在学习这个技术的朋友.通过学习Beautiful Soup基础知识 完成了一个简单的爬虫服务:从all ...

  3. 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(1): 基础知识Beautiful Soup

    开始学习网络数据挖掘方面的知识,首先从Beautiful Soup入手(Beautiful Soup是一个Python库,功能是从HTML和XML中解析数据),打算以三篇博文纪录学习Beautiful ...

  4. Python爬虫学习(11):Beautiful Soup的使用

    之前我们从网页中提取重要信息主要是通过自己编写正则表达式完成的,但是如果你觉得正则表达式很好写的话,那你估计不是地球人了,而且很容易出问题.下边要介绍的Beautiful Soup就可以帮你简化这些操 ...

  5. 推荐一些python Beautiful Soup学习网址

    前言:这几天忙着写分析报告,实在没精力去研究django,虽然抽时间去看了几遍中文文档,还是等实际实践后写几篇操作文章吧! 正文:以下是本人前段时间学习bs4库找的一些网址,在学习的可以参考下,有点多 ...

  6. 错误 You are trying to run the Python 2 version of Beautiful Soup under Python 3. This will not work

    Win  10    下python3.6 使用Beautiful Soup  4错误 You are trying to run the Python 2 version of Beautiful ...

  7. Python学习笔记之Beautiful Soup

    如何在Python3.x中使用Beautiful Soup 1.BeautifulSoup中文文档:http://www.crummy.com/software/BeautifulSoup/bs3/d ...

  8. Python Beautiful Soup学习之HTML标签补全功能

    Beautiful Soup是一个非常流行的Python模块.该模块可以解析网页,并提供定位内容的便捷接口. 使用下面两个命令安装: pip install beautifulsoup4 或者 sud ...

  9. 转:Beautiful Soup

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...

随机推荐

  1. Python学习教程(learning Python)--1.4 Python数据处理基础

    本节主要讨论数据操作及运算符等基础知识,熟悉C语言相关知识的读者请跳过此节. 在高级语言编程过程中,有了数据以后通常要对数据进行相应的数据处理,加.减.乘.除等基本运算,不难理解. 在Python里 ...

  2. DTAP street

    一个网站程序的上线一般要经过开发[Development]测试[Testing]验收[Acceptance]生产[Production].所以又叫做DTAP street.对应有开发环境.测试环境.验 ...

  3. 浅谈iOS网络编程之一入门

    计算机网络,基本上可以抽象是端的通信.实际在通讯中会用到不同的设备,不同的硬件中,为了能友好的传输信息,那么建立一套规范就十分必要了.先来了解一些基本概念 了解网络中传输的都是二进制数据流.  2.了 ...

  4. 小心指针被delete两次

    C++类中,有时候使用到传值调用(对象实体做参数),遇到这种情况,可要小心了!特别是当你所传值的对象生命周期较长,而非临时对象(生命周期段)的时候.来看看下面的情况: #include <ios ...

  5. js-提前声明和new操作符理解

    1.提前声明:声明变量后,js会把声明部分提前到作用域前面. var a=1; function aheadOfStatement(){ alert(a); var a=2; } 这段代码结果是und ...

  6. ExpressJS File Uploading – GridFS – MongoDB

    n this blog post we will see how to handle multipart data/file uploading with expressjs. Save files ...

  7. 集成友盟分享SDK报错

    删除4.2.1版本的reference换成4.3版本运行报错 解决办法:要将4.2.1版本的全部库文件物理删除,不要只删除reference.

  8. 将获得到的json赋值到下拉框

    $(function () { $.getJSON('handler/addEmployees.ashx', function (json) { alert(json.length); //遍历赋值 ...

  9. Labview实现单边带信号调制(SSB)[移相法]

    Labview实现单边带信号调制(SSB)[移相法] 时域上的表达式为 调制器模型为 这个实验中需要相位偏移比较多,因为一共用了四个信号仿真器,一个是无偏移的调制信号,一个是偏移的调制信号,一个是无偏 ...

  10. 【学习总结】iOS中NSNotification、delegate、KVO三者之间的区别与联系?

    在开发ios应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers间怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信: 1.委托delegation: 2.通 ...