HDU 4868 Information Extraction

看到这道题时我的内心是奔溃的,没有了解过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 }
时间: 2025-01-18 12:52:11

HDU 4868 Information Extraction的相关文章

[IR] Information Extraction

阶段性总结 Boolean retrieval 单词搜索 [Qword1 and Qword2]               O(x+y) [Qword1 and Qword2]- 改进: Galloping Search   O(2a*log2(b/a)) [Qword1 and not Qword2]        O(m*log2n)  [Qword1 or not Qword2]           O(m+n) [Qword1 and Qword2 and Qword3 and ...

Maximum Entropy Markov Models for Information Extraction and Segmentation

1.The use of state-observation transition functions rather than the separate transition and observation functions in HMMs allows us to model transitions in terms of multiple, nonindependent features of observations, which we believe to be the most va

HDU 3586.Information Disturbing 树形dp

Information Disturbing Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 3205    Accepted Submission(s): 1137 Problem Description In the battlefield , an effective way to defeat enemies is to bre

HDU 3586 Information Disturbing 树形DP+二分

Information Disturbing Problem Description In the battlefield , an effective way to defeat enemies is to break their communication system.The information department told you that there are n enemy soldiers and their network which have n-1 communicati

HDU 3586 Information Disturbing (二分+树形dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3586 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限limit,问切断所有前线与司令部联系所花费的总费用少于m时的最小limit.1<=n<=1000,1<=m<=10^6 dp[i]表示i节点为root的这个子树所破坏的最少费用,if(cost[i]

HDU 3586 Information Disturbing(二分+树形dp)

http://acm.split.hdu.edu.cn/showproblem.php?pid=3586 题意: 给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit. 思路: 对于上限limit我们可以二分查找.然后就是树形dp,看代码就可以理解的. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring>

hdu 3586 Information Disturbing (树形dp)

Information Disturbing Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 1722    Accepted Submission(s): 641 Problem Description In the battlefield , an effective way to defeat enemies is to bre

HDU 3586 Information Disturbing

二分+树形DP验证. 答案是通过二分查找得到的,对于每一次二分到的值,进行验证,是否可行. 可以用树形DP来求解所有叶子节点不能向根节点传送消息的最小费用,dp[i] 表示 节点i 的子树的叶子结点都不能向i传送消息的最小费用,这样很容易递推. #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<map> #include<vector>

HDU 3586 Information Disturbing (树形DP,二分)

题意: 给定一个敌人的通信系统,是一棵树形,每个节点是一个敌人士兵,根节点是commander,叶子是前线,我们的目的是使得敌人的前线无法将消息传到commander,需要切断一些边,切断每条边需要一定的power,而我们有一台具有m点power的机器,问在使用此机器切断敌人通信系统的情况下,使得所切断边的最大边权达到最小是多少?(m<=100w,n<=1000) 思路: 其实就是要求所切断的边的最小瓶颈边.由于m比较大,不好枚举或者DP.但是他们具有线性的关系,就是瓶颈边越大,肯定越容易有解