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;

}
View Code

 

你可能感兴趣的:(HDU)