HDU 4868 Information Extraction(2014 多校联合第一场 H)

看到这道题时我的内心是奔溃的,没有了解过HTML,只能靠窝的渣渣英语一点一点翻译啊TT、

Information Extraction

题意:(纯手工翻译,有些用词可能在html中不是一样的,还多包涵)
从HTML文档中提取信息,用一种特殊的格式输出。
HTML文件的定义如下:
HTML:
   是一种超文本标记语言。标记语言是由一系列的标记组成的。

 标签描述文档内容。HTML文件由标签和文本组成。
标签:
   HTML使用标签来实现他的语法。

   标签由特殊的字符(如: ‘<’, ‘>’ and ‘/’)组成。

   标签通常成对出现,起始标签和结束标签。起始标签以<开头,>结尾。

   结束标签以</开头,以>结尾。文件的其他地方不会出现尖括号。

   标签名是只含有小写字母的字符串。标签中没有行中断。

   除了标签,文件中出现的其他东西都被认为是文本内容。

   标签名的长度不超过30.
元素:
   元素是起始标签和相对应的终止标签之间的任何内容,包括标签在内。

   元素内容是开始标签和结束标签之间的内容。

   有些元素没有内容,我们叫它空元素,如 <hr></hr>。

   空元素可以被关在一个打开标签内,以/>结尾,而不是>。

   所有元素都可以被关闭用关闭标签或者在开始标签里面。

   元素可以有属性。

   元素可以被嵌套,即一个元素可以包含另一个元素。

   <html>元素师其他所有元素的容器,他不包含任何属性。
属性:
   属性为元素提供额外信息。

   属性总是在开始标签中被规定,在标签名的后面。

   标签名和属性由一个空格隔开。

   一个元素可以有多个属性。

   属性以这样的形式出现:name="value" class="icpc",等号两边没有空格。

   所有的属性名都是小写的。

   id属性的值是唯一的,长度小于等于30.

 

题目中还给了几个例子,我们来看一下:

sample 1: 

<html><body>  //<html>是总容器,<body>是标签
<h3 id="header" class="style1">this is a test</h3>   //<h3 id="header" class="style1">是起始标签,标签名是h3,有两个属性,id和class。“this is a test”是元素。</h3>是结束标签。
<div id="content" class="style2">   //<div> 标签,同上。
this is content<br/>
<pre>var x = 1111; </pre>
</div>
</body></html>  //结束标签

 

由结构到输出格式的映射如下:

id属性的值-输出格式的标签名

 

输入:

T:代表有几组样例。

每一个样例都在前面规定它的输出格式。

n:有几种html文件

每一种类型的l结构在之前的html文件中

m: 有几种映射从结构到输出结果

m行映射

最后是html测试案例

 

输出:

每一组样例,第一行输出“Case #x”

如果存在这种结构的html文件,按格式输出,否则,输出“Can't Identify”如果有多种结构,使用最早输入的结构。

 

下面我们来分析一样题目给出的测试数据:

input:

2 <news> <title>default title</title> <content width="1000px"></content> </news> 1 <html><h3 id="header"></h3> <div id="content"></div></html> 2 header-title content-content <html><h3 id="header" class="style1"> this is a test</h3> <div id="content" class="style2"> this is content<br/> <pre>var x = 1111;</pre> </div> </html> <xxx> <title>default title</title> </xxx> 1 <html><h3 id="header"></h3></html> 1 header-title <html><h3 id="tmp">xxxx</h3></html>

 

output:

Case #1: <news> <title> this is a test</title> <content width="1000px"> this is content<br/> <pre>var x = 1111;</pre> </content> </news>

Case #2: Can't Identify

 

输入分析:

蓝色部分规定了输出格式,绿色部分规定了html文件的结构,红色部分为m种映射,紫色部分是需要提取信息的文本。

 

拿case 1 来看,<html><h3 id="header" class="style1"> this is a test</h3> <div id="content" class="style2"> this is content<br/> <pre>var x = 1111;</pre> </div> </html>   从中我们可以得出的信息为 标签h3,它的属性id的值为header,上述header的映射为title,所以用标签为title 的格式输出“<title> this is a test</title>”  接下来是div标签,它的属性id的值为content,上述content的映射为content,所以用标签为content的格式输出“ <content width="1000px"> this is content<br/> <pre>var x = 1111;</pre> </content>”,在前后分别加上<news></news>;

case 2:找不到属性值为tmp的映射,所以不能定义。

 

题意,样例都说完了,下面来看看代码吧(不是本人写的):

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<string.h>
  4 using namespace std;
  5 const int N=10010;
  6 const int M=35;
  7 char html[M][N],stored[M][N],sta1[N][M];
  8 char mapping[M][M][2][M];//存储映射情况
  9 int mapNum[M],sta2[N];
 10 void getHtmlFormat(int n)//读取html的格式
 11 {
 12     int j,i=0,flag=1;
 13     char beginTag[M];//存储开始标签
 14     char tag[M];//存储标签
 15     getchar();
 16     while(1)
 17     {
 18         html[n][i]=getchar();//读取第n个html
 19         if(html[n][i]=='<')
 20         {
 21             j=0;
 22             while(html[n][++i]=getchar())
 23             {
 24                 if(html[n][i]=='/')
 25                     continue;
 26                 if(html[n][i]==' '||html[n][i]=='>')
 27                     break;
 28                 tag[j++]=html[n][i];
 29             }
 30             tag[j]='\0';
 31             if(flag==1)
 32             {
 33                 strcpy(beginTag,tag);
 34                 flag=0;
 35             }
 36             else if(!strcmp(tag,beginTag))//表示读到结束标签,读取结束
 37             {
 38                 html[n][++i]='\0';
 39                 return;
 40             }
 41         }
 42         i++;
 43     }
 44 }
 45 void getMapping(int n,int m)
 46 {
 47     int i,j;
 48     char mp[100];
 49     cin>>mp;
 50     for(i=0; mp[i]!='-'; i++)
 51         mapping[n][m][0][i]=mp[i];
 52     mapping[n][m][0][i]='\0';
 53     for(j=0,i++; i<strlen(mp); i++,j++)
 54         mapping[n][m][1][j]=mp[i];
 55     mapping[n][m][1][j]='\0';
 56 }
 57 void getTag(int n,int i,char tag[])
 58 {
 59     int j=0;
 60     while(1)
 61     {
 62         i++;
 63         if(html[n][i]=='/')
 64             continue;
 65         if(html[n][i]==' '||html[n][i]=='>')
 66             break;
 67         tag[j++]=html[n][i];
 68     }
 69     tag[j]='\0';
 70 }
 71 int getId(int n,int i,char id[])
 72 {
 73     int j;
 74     id[0]='\0';
 75     char tmp[M];
 76     while(html[n][i]==' ')
 77     {
 78         j=0;
 79         while(html[n][++i]!='=')
 80             tmp[j++]=html[n][i];
 81         tmp[j]='\0';
 82         if(!strcmp(tmp,"id"))
 83         {
 84             i++;
 85             j=0;
 86             while(html[n][++i]!='"')
 87                 id[j++]=html[n][i];
 88             id[j]='\0';
 89         }
 90         else
 91         {
 92             i++;
 93             while(html[n][++i]!='"');
 94         }
 95         i++;
 96     }
 97     return i;
 98 }
 99 void store(int n,int i,int j,char tag[])
100 {
101     stored[j][0]='\0';
102     int k,y=0,flag=0,len=strlen(tag);
103     for(i++;; i++)
104     {
105         k=0;
106         if(html[n][i]=='<')
107             for(; k<len; k++)
108                 if(tag[k]!=html[n][i+1+k])break;
109         if(k==len)flag++;
110         k=0;
111         if(html[n][i]=='<'&&html[n][i+1]=='/')
112             for(; k<len; k++)
113                 if(tag[k]!=html[n][i+2+k])break;
114         if(k==len)
115         {
116             if(!flag)
117             {
118                 stored[j][y]='\0';
119                 return;
120             }
121             else flag--;
122         }
123         stored[j][y++]=html[n][i];
124     }
125 }
126 bool isStructure(int n,int m)
127 {
128     int i,j,k,ii,flag=0,top=-1;
129     char tag[M],id[M],tag2[M],id2[M];
130     int len1=strlen(html[n]);
131     for(i=k=0; i<len1;)
132     {
133         ii=i;
134         while(html[n][i]==' '||html[n][i]=='\n')
135             i++;
136         while(html[m][k]!='<')
137             k++;
138         getTag(n,i,tag);//获取标签
139         getTag(m,k,tag2);
140         if(strcmp(tag,tag2)||html[n][i+1]!=html[m][k+1])
141         {
142             if(!strcmp(tag,tag2))
143                 sta2[top]++;
144             if(!flag)
145             {
146                 return false;
147             }
148             while(html[m][k]!='>')
149                 k++;
150             i=ii;
151             continue;
152         }
153         if(html[n][i+1]=='/') //</xx>
154         {
155             if(!sta2[top])
156             {
157                 i+=strlen(tag)+3;
158                 flag--;
159             }
160             else sta2[top]--;
161             k+=strlen(tag)+3;
162         }
163         else  //<xx>或者<xx/>
164         {
165             i+=strlen(tag)+1;
166             k+=strlen(tag2)+1;
167             if(html[n][i]==' ') //有id
168             {
169                 if(html[m][k]!=' ')
170                 {
171                     if(!flag)
172                     {
173                         return false;
174                     }
175                     while(html[m][k]!='>')k++;
176                     i=ii;
177                     continue;
178                 }
179                 i=getId(n,i,id);
180                 k=getId(m,k,id2);
181                 if(strcmp(id,id2))
182                 {
183                     if(!flag)
184                     {
185                         return false;
186                     }
187                     while(html[m][k]!='>')k++;
188                     i=ii;
189                     continue;
190                 }
191             }
192             for(j=0; j<mapNum[n]; j++)
193                 if(!strcmp(id,mapping[n][j][0]))
194                     break;
195             if(html[n][i]=='/') //<xx/>
196             {
197                 i+=2;
198                 k+=2;
199             }
200             else  //<xx>
201             {
202                 if(j!=mapNum[n]) //需映射的id
203                 {
204                     strcpy(sta1[++top],tag);
205                     flag++;
206                     sta2[top]=0;
207                     for(j=0; j<mapNum[n]; j++)
208                         if(!strcmp(id,mapping[n][j][0]))
209                             store(m,k,j,tag);
210                 }
211                 i++;
212                 k++;
213             }
214         }
215     }
216     return true;
217 }
218 void output(int n)
219 {
220     int i,j,k,ii;
221     char tag[M];
222     int len1=strlen(html[0]);
223     for(i=0; i<len1;)
224     {
225         while(i<len1&&html[0][i]!='<')
226             putchar(html[0][i++]);
227         if(i==len1)break;
228         getTag(0,i,tag);
229         for(j=0; j<mapNum[n]; j++)
230             if(!strcmp(tag,mapping[n][j][1]))
231                 break;
232         if(j==mapNum[n])
233         {
234             putchar(html[0][i++]);
235             continue;
236         }
237         else
238         {
239             int len=strlen(tag);
240             ii=i;
241             for(i+=len+1;; i++)
242             {
243                 k=0;
244                 if(html[0][i]=='<'&&html[0][i+1]=='/')
245                     for(; k<len; k++)
246                         if(tag[k]!=html[0][i+2+k])
247                             break;
248                 if(k==len)
249                     break;
250             }
251             while(html[0][ii]!='>')
252                 putchar(html[0][ii++]);
253             putchar(html[0][ii++]);
254             cout<<stored[j];
255             while(html[0][i]!='>')
256                 putchar(html[0][i++]);
257             putchar(html[0][i++]);
258         }
259     }
260 }
261 int main()
262 {
263     int T;
264     scanf("%d",&T);
265     for(int cases=1;cases<=T;cases++)
266     {
267         int i,j,n,m;
268         getHtmlFormat(0);
269         scanf("%d",&n);
270         for(i=1; i<=n; i++)
271         {
272             getHtmlFormat(i);
273             scanf("%d",&mapNum[i]);
274             for(j=0; j<mapNum[i]; j++)
275                 getMapping(i,j);
276         }
277         getHtmlFormat(n+1);// 待处理的html文件
278         printf("Case #%d:\n",cases);
279         for(i=1; i<=n; i++)
280             if(isStructure(i,n+1))
281             {
282                 output(i);
283                 break;
284             }
285         if(i==n+1)
286             printf("Can't Identify");
287         putchar('\n');
288     }
289     return 0;
290 }

 

posted @ 2015-07-12 17:08  PJQOOO  阅读(609)  评论(0编辑  收藏  举报