HDU 4782 Beautiful Soup --模拟
题意: 将一些分散在各行的HTML代码整理成标签树的形式。
解法: 模拟,具体见代码的讲解。 开始没考虑 '\t' 。。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <string> using namespace std; string S,tmp,pre; int main() { int t,i,j,cs = 1; scanf("%d",&t); getchar(); pre = ""; while(t--) { S = ""; int fir = 1; //是否是第一个子串 while(1) { getline(cin,tmp,'\n'); if(fir) { tmp = pre + tmp; S = S + tmp; fir = 0; } //如果是第一个子串,看有没有遗留在前面case的部分 else S = S + " " + tmp; int ls = S.length(); int lt = tmp.length(); int tag = 1; for(i=0;i<=lt-7;i++) //读入 { if(tmp.substr(i,7) == "</html>") { S = S.substr(0,ls-lt+i+7); pre = tmp.substr(i+7,lt-i-7); tag = 0; break; } } if(!tag) break; } int len = S.length(), deep = 0; printf("Case #%d:\n",cs++); for(i=0;i<len;i++) if(S[i] == '\t') S[i] = ' '; //把Tab转换掉 //cout<<"S = "<<S<<endl; for(i=0;i<len;i++) { if(S[i] == '<') //标签部分 { if(S[i+1] != '/') deep++; // 1.开标签,深度+ else deep--; // 2.闭标签,深度- for(j=0;j<deep-(S[i+1]=='/'?0:1);j++) printf(" "); //如果是闭标签,不用减一个空格,否则要建一个空格输出,因为开始就deep++了 if(S[i+1] != '/') //如果是类似 <hr/> 的空标签,deep--抵消开标签的deep++ { for(j=i;S[j]!='>' && j < len;j++); if(S[j-1] == '/') deep--; } for(i;S[i]!='>';i++) cout<<S[i]; //输出标签内容 cout<<">"<<endl; } else //正文部分,空格地方小心处理 { string buf = ""; //缓冲部分 int letter = 0; while(S[i] != '<' && i < len) { if(S[i] == ' ') //除掉文字前面的空格 { while(S[i] == ' ' && i < len) i++; i--; } if(S[i] == ' ' && (S[i+1] == '<' || !letter)) { i++; continue; } //如果文本全是空格,i++,继续 letter = 1; //否则,有字母 buf += S[i]; //推进缓冲区 i++; } if(letter) //如果文本有内容 { for(j=0;j<deep;j++) printf(" "); //再打deep个空格 cout<<buf; //输出缓冲区内容 puts(""); } i--; } } } return 0; }
作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com