看到这道题时我的内心是奔溃的,没有了解过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=;
  6. const int M=;
  7. char html[M][N],stored[M][N],sta1[N][M];
  8. char mapping[M][M][][M];//存储映射情况
  9. int mapNum[M],sta2[N];
  10. void getHtmlFormat(int n)//读取html的格式
  11. {
  12. int j,i=,flag=;
  13. char beginTag[M];//存储开始标签
  14. char tag[M];//存储标签
  15. getchar();
  16. while()
  17. {
  18. html[n][i]=getchar();//读取第n个html
  19. if(html[n][i]=='<')
  20. {
  21. j=;
  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==)
  32. {
  33. strcpy(beginTag,tag);
  34. flag=;
  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[];
  49. cin>>mp;
  50. for(i=; mp[i]!='-'; i++)
  51. mapping[n][m][][i]=mp[i];
  52. mapping[n][m][][i]='\0';
  53. for(j=,i++; i<strlen(mp); i++,j++)
  54. mapping[n][m][][j]=mp[i];
  55. mapping[n][m][][j]='\0';
  56. }
  57. void getTag(int n,int i,char tag[])
  58. {
  59. int j=;
  60. while()
  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';
  75. char tmp[M];
  76. while(html[n][i]==' ')
  77. {
  78. j=;
  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=;
  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';
  102. int k,y=,flag=,len=strlen(tag);
  103. for(i++;; i++)
  104. {
  105. k=;
  106. if(html[n][i]=='<')
  107. for(; k<len; k++)
  108. if(tag[k]!=html[n][i++k])break;
  109. if(k==len)flag++;
  110. k=;
  111. if(html[n][i]=='<'&&html[n][i+]=='/')
  112. for(; k<len; k++)
  113. if(tag[k]!=html[n][i++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=,top=-;
  129. char tag[M],id[M],tag2[M],id2[M];
  130. int len1=strlen(html[n]);
  131. for(i=k=; 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+]!=html[m][k+])
  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+]=='/') //</xx>
  154. {
  155. if(!sta2[top])
  156. {
  157. i+=strlen(tag)+;
  158. flag--;
  159. }
  160. else sta2[top]--;
  161. k+=strlen(tag)+;
  162. }
  163. else //<xx>或者<xx/>
  164. {
  165. i+=strlen(tag)+;
  166. k+=strlen(tag2)+;
  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=; j<mapNum[n]; j++)
  193. if(!strcmp(id,mapping[n][j][]))
  194. break;
  195. if(html[n][i]=='/') //<xx/>
  196. {
  197. i+=;
  198. k+=;
  199. }
  200. else //<xx>
  201. {
  202. if(j!=mapNum[n]) //需映射的id
  203. {
  204. strcpy(sta1[++top],tag);
  205. flag++;
  206. sta2[top]=;
  207. for(j=; j<mapNum[n]; j++)
  208. if(!strcmp(id,mapping[n][j][]))
  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[]);
  223. for(i=; i<len1;)
  224. {
  225. while(i<len1&&html[][i]!='<')
  226. putchar(html[][i++]);
  227. if(i==len1)break;
  228. getTag(,i,tag);
  229. for(j=; j<mapNum[n]; j++)
  230. if(!strcmp(tag,mapping[n][j][]))
  231. break;
  232. if(j==mapNum[n])
  233. {
  234. putchar(html[][i++]);
  235. continue;
  236. }
  237. else
  238. {
  239. int len=strlen(tag);
  240. ii=i;
  241. for(i+=len+;; i++)
  242. {
  243. k=;
  244. if(html[][i]=='<'&&html[][i+]=='/')
  245. for(; k<len; k++)
  246. if(tag[k]!=html[][i++k])
  247. break;
  248. if(k==len)
  249. break;
  250. }
  251. while(html[][ii]!='>')
  252. putchar(html[][ii++]);
  253. putchar(html[][ii++]);
  254. cout<<stored[j];
  255. while(html[][i]!='>')
  256. putchar(html[][i++]);
  257. putchar(html[][i++]);
  258. }
  259. }
  260. }
  261. int main()
  262. {
  263. int T;
  264. scanf("%d",&T);
  265. for(int cases=;cases<=T;cases++)
  266. {
  267. int i,j,n,m;
  268. getHtmlFormat();
  269. scanf("%d",&n);
  270. for(i=; i<=n; i++)
  271. {
  272. getHtmlFormat(i);
  273. scanf("%d",&mapNum[i]);
  274. for(j=; j<mapNum[i]; j++)
  275. getMapping(i,j);
  276. }
  277. getHtmlFormat(n+);// 待处理的html文件
  278. printf("Case #%d:\n",cases);
  279. for(i=; i<=n; i++)
  280. if(isStructure(i,n+))
  281. {
  282. output(i);
  283. break;
  284. }
  285. if(i==n+)
  286. printf("Can't Identify");
  287. putchar('\n');
  288. }
  289. return ;
  290. }

HDU 4868 Information Extraction(2014 多校联合第一场 H)的更多相关文章

  1. hdu 4869 Turn the pokers (2014多校联合第一场 I)

    Turn the pokers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. hdu 4865 Peter&#39;s Hobby(2014 多校联合第一场 E)

    Peter's Hobby Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  3. HDU 4870 Rating (2014 多校联合第一场 J)(概率)

    题意: 一个人有两个TC的账号,一开始两个账号rating都是0,然后每次它会选择里面rating较小的一个账号去打比赛,每次比赛有p的概率+1分,有1-p的概率-2分,当然如果本身是<=2分的 ...

  4. HDU 4869 Turn the pokers (2014 多校联合第一场 I)

    HDOJ--4869--Turn the pokers[组合数学+快速幂] 题意:有m张扑克,开始时全部正面朝下,你可以翻n次牌,每次可以翻xi张,翻拍规则就是正面朝下变背面朝下,反之亦然,问经过n次 ...

  5. HDU 4865 Peter's Hobby(2014 多校联合第一场 E)(概率dp)

    题意:已知昨天天气与今天天气状况的概率关系(wePro),和今天天气状态和叶子湿度的概率关系(lePro)第一天为sunny 概率为 0.63,cloudy 概率 0.17,rainny 概率 0.2 ...

  6. hdu 5288||2015多校联合第一场1001题

    pid=5288">http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a ar ...

  7. HDU 5724 Chess (状态压缩sg函数博弈) 2016杭电多校联合第一场

    题目:传送门. 题意:有n行,每行最多20个棋子,对于一个棋子来说,如果他右面没有棋子,可以移动到他右面:如果有棋子,就跳过这些棋子移动到后面的空格,不能移动的人输. 题解:状态压缩博弈,对于一行2^ ...

  8. HDU 5289 Assignment(多校联合第一场1002)

    Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...

  9. hdu5294||2015多校联合第一场1007 最短路+最大流

    http://acm.hdu.edu.cn/showproblem.php? pid=5294 Problem Description Innocent Wu follows Dumb Zhang i ...

随机推荐

  1. java--String方法

    String : 字符串类型 一.构造函数 String(byte[ ] bytes):通过byte数组构造字符串对象. String(char[ ] value):通过char数组构造字符串对象. ...

  2. 转:DNS拾遗

    最近帮朋友注册域名配置主机,碰到一些DNS上的一些概念,惭愧于有一些东西已经忘记是啥意思,于是决定重新学习一下DNS方面的基本概念. 常用概念: TTL: TTL为Time to live的缩写,网络 ...

  3. android getDecorView()的作用

    decorView是window中的最顶层view,可以从window中通过getDecorView获取到decorView.通过decorView获取到程序显示的区域,包括标题栏,但不包括状态栏.间 ...

  4. javascript语言精粹:继承

    继承提供了2个有用的任务: 1.代码重用 2.引入了一套类型系统的规范,因为程序员无需编写显示类型转换的代码,他们的工作量将大大减轻.这是一件很好的事情,应为类型转换会丧失类型系统在安全上的优势. 在 ...

  5. 不老的新丁 Python何以让人着迷

    Python是一门美丽的语言.它简单易学,跨平台,而且运转良好.达成了许多Java一直求索的技术目标.一言以蔽之就是:其他的语言是与时代同 步,而Python则是未雨绸缪,而且计划得颇为出色.当然,这 ...

  6. BNU 26579 Andrew the Ant 【蚂蚁】

    链接: http://www.bnuoj.com/bnuoj/problem_show.php?pid=26579 http://www.bnuoj.com/bnuoj/contest_show.ph ...

  7. 安卓开发-Activity中finish() onDestroy() 和System.exit()的区别

    Activity.finish()Call this when your activity is done and should be closed. 在你的activity动作完成的时候,或者Act ...

  8. sql基础,必须会的————随便整理、杂乱无章

    1.sqlserver2008r2的安装 2.数据库与表的建立.增加.删除.修改. 3,索引的概念,包括聚集与非聚集的区别.全文索引的建立与如何使用全文索引. 4,重新生成索引,重新组织索引. 5,建 ...

  9. ZOJ 3609 求逆元

    Modular Inverse Time Limit: 2 Seconds      Memory Limit: 65536 KB The modular modular multiplicative ...

  10. Mysql事务,并发问题,锁机制-- 幻读、不可重复读(转)

    1.什么是事务 事务是一条或多条数据库操作语句的组合,具备ACID,4个特点. 原子性:要不全部成功,要不全部撤销 隔离性:事务之间相互独立,互不干扰 一致性:数据库正确地改变状态后,数据库的一致性约 ...