看到这道题时我的内心是奔溃的,没有了解过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的映射,所以不能定义。

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

 #include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int N=;
const int M=;
char html[M][N],stored[M][N],sta1[N][M];
char mapping[M][M][][M];//存储映射情况
int mapNum[M],sta2[N];
void getHtmlFormat(int n)//读取html的格式
{
int j,i=,flag=;
char beginTag[M];//存储开始标签
char tag[M];//存储标签
getchar();
while()
{
html[n][i]=getchar();//读取第n个html
if(html[n][i]=='<')
{
j=;
while(html[n][++i]=getchar())
{
if(html[n][i]=='/')
continue;
if(html[n][i]==' '||html[n][i]=='>')
break;
tag[j++]=html[n][i];
}
tag[j]='\0';
if(flag==)
{
strcpy(beginTag,tag);
flag=;
}
else if(!strcmp(tag,beginTag))//表示读到结束标签,读取结束
{
html[n][++i]='\0';
return;
}
}
i++;
}
}
void getMapping(int n,int m)
{
int i,j;
char mp[];
cin>>mp;
for(i=; mp[i]!='-'; i++)
mapping[n][m][][i]=mp[i];
mapping[n][m][][i]='\0';
for(j=,i++; i<strlen(mp); i++,j++)
mapping[n][m][][j]=mp[i];
mapping[n][m][][j]='\0';
}
void getTag(int n,int i,char tag[])
{
int j=;
while()
{
i++;
if(html[n][i]=='/')
continue;
if(html[n][i]==' '||html[n][i]=='>')
break;
tag[j++]=html[n][i];
}
tag[j]='\0';
}
int getId(int n,int i,char id[])
{
int j;
id[]='\0';
char tmp[M];
while(html[n][i]==' ')
{
j=;
while(html[n][++i]!='=')
tmp[j++]=html[n][i];
tmp[j]='\0';
if(!strcmp(tmp,"id"))
{
i++;
j=;
while(html[n][++i]!='"')
id[j++]=html[n][i];
id[j]='\0';
}
else
{
i++;
while(html[n][++i]!='"');
}
i++;
}
return i;
}
void store(int n,int i,int j,char tag[])
{
stored[j][]='\0';
int k,y=,flag=,len=strlen(tag);
for(i++;; i++)
{
k=;
if(html[n][i]=='<')
for(; k<len; k++)
if(tag[k]!=html[n][i++k])break;
if(k==len)flag++;
k=;
if(html[n][i]=='<'&&html[n][i+]=='/')
for(; k<len; k++)
if(tag[k]!=html[n][i++k])break;
if(k==len)
{
if(!flag)
{
stored[j][y]='\0';
return;
}
else flag--;
}
stored[j][y++]=html[n][i];
}
}
bool isStructure(int n,int m)
{
int i,j,k,ii,flag=,top=-;
char tag[M],id[M],tag2[M],id2[M];
int len1=strlen(html[n]);
for(i=k=; i<len1;)
{
ii=i;
while(html[n][i]==' '||html[n][i]=='\n')
i++;
while(html[m][k]!='<')
k++;
getTag(n,i,tag);//获取标签
getTag(m,k,tag2);
if(strcmp(tag,tag2)||html[n][i+]!=html[m][k+])
{
if(!strcmp(tag,tag2))
sta2[top]++;
if(!flag)
{
return false;
}
while(html[m][k]!='>')
k++;
i=ii;
continue;
}
if(html[n][i+]=='/') //</xx>
{
if(!sta2[top])
{
i+=strlen(tag)+;
flag--;
}
else sta2[top]--;
k+=strlen(tag)+;
}
else //<xx>或者<xx/>
{
i+=strlen(tag)+;
k+=strlen(tag2)+;
if(html[n][i]==' ') //有id
{
if(html[m][k]!=' ')
{
if(!flag)
{
return false;
}
while(html[m][k]!='>')k++;
i=ii;
continue;
}
i=getId(n,i,id);
k=getId(m,k,id2);
if(strcmp(id,id2))
{
if(!flag)
{
return false;
}
while(html[m][k]!='>')k++;
i=ii;
continue;
}
}
for(j=; j<mapNum[n]; j++)
if(!strcmp(id,mapping[n][j][]))
break;
if(html[n][i]=='/') //<xx/>
{
i+=;
k+=;
}
else //<xx>
{
if(j!=mapNum[n]) //需映射的id
{
strcpy(sta1[++top],tag);
flag++;
sta2[top]=;
for(j=; j<mapNum[n]; j++)
if(!strcmp(id,mapping[n][j][]))
store(m,k,j,tag);
}
i++;
k++;
}
}
}
return true;
}
void output(int n)
{
int i,j,k,ii;
char tag[M];
int len1=strlen(html[]);
for(i=; i<len1;)
{
while(i<len1&&html[][i]!='<')
putchar(html[][i++]);
if(i==len1)break;
getTag(,i,tag);
for(j=; j<mapNum[n]; j++)
if(!strcmp(tag,mapping[n][j][]))
break;
if(j==mapNum[n])
{
putchar(html[][i++]);
continue;
}
else
{
int len=strlen(tag);
ii=i;
for(i+=len+;; i++)
{
k=;
if(html[][i]=='<'&&html[][i+]=='/')
for(; k<len; k++)
if(tag[k]!=html[][i++k])
break;
if(k==len)
break;
}
while(html[][ii]!='>')
putchar(html[][ii++]);
putchar(html[][ii++]);
cout<<stored[j];
while(html[][i]!='>')
putchar(html[][i++]);
putchar(html[][i++]);
}
}
}
int main()
{
int T;
scanf("%d",&T);
for(int cases=;cases<=T;cases++)
{
int i,j,n,m;
getHtmlFormat();
scanf("%d",&n);
for(i=; i<=n; i++)
{
getHtmlFormat(i);
scanf("%d",&mapNum[i]);
for(j=; j<mapNum[i]; j++)
getMapping(i,j);
}
getHtmlFormat(n+);// 待处理的html文件
printf("Case #%d:\n",cases);
for(i=; i<=n; i++)
if(isStructure(i,n+))
{
output(i);
break;
}
if(i==n+)
printf("Can't Identify");
putchar('\n');
}
return ;
}

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. ZOJ 1450 Minimal Circle 最小圆覆盖

    套了个模板直接上,貌似没有随机化序列 QAQ //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #in ...

  2. 互联网创业十问?good(快速迭代、把握核心用户应对抄袭,不需要把商业模式考虑完备,4种失败的信号,失败者没资格说趁着年轻...)

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:曹政链接:https://www.zhihu.com/question/20264499/answer/28168079来源: ...

  3. redis(二)redis+TCMALLOC高性能的缓存服务器的安装配置

    安装  1准备编译环境    yum -y install gcc gcc+ gcc-c++ openssl openssl-devel pcre pcre-devel  2 下载源码包(由于goog ...

  4. Derby的下载安装和使用,(和JAVA中使用Derby)

    首先是Java环境变量要配置: 1.打开我的电脑--属性--高级--环境变量 2.新建系统变量JAVA_HOME 和CLASSPATH 变量名:JAVA_HOME 变量值:C:\Program Fil ...

  5. JAVA学习第三十六课(经常使用对象API)— Set集合:HashSet集合演示

    随着Java学习的深入,感觉大一时搞了一年的ACM,简直是明智之举,Java里非常多数据结构.算法类的东西,理解起来就轻松多了 Set集合下有两大子类开发经常使用 HashSet集合 .TreeSet ...

  6. Win8.1应用开发之异步编程

    在win8应用商店开发时,我们会遇到很多异步方法.它们存在的目的就是为了确保你的应用在运行须要大量时间的任务时仍能保持良好的响应,也就是说调用异步API是为了响应用户的操作.设想一下我们点击一个But ...

  7. QTabWidget 实现类似QQ聊天窗口(拖动分离出新的窗口)

    新版本的QQ聊天窗口可以实现拖动,分离出新的窗口.浏览器等软件也可以实现类似操作.所以心血来潮想用Qt实现类似的功能.想用QTabWidget直接实现是很难的,仔细阅读源码,发现QTabWidget内 ...

  8. js获取地址栏url以及获取url参数

    js原生态写法  代码如下 复制代码 function getUrlParam(name) {     var reg = new RegExp("(^|&)"+ name ...

  9. MONGODB的内部构造 FROM 《MONGODB THE DEFINITIVE GUIDE》

    今天下载了<MongoDB The Definitive Guide>电子版,浏览了里面的内容,还是挺丰富的.是官网文档实际应用方面的一个补充.和官方文档类似,介绍MongoDB的内部原理 ...

  10. Java--Http向服务端提交字条串数据

    package com.joye3g.http; import java.io.BufferedReader; import java.io.DataOutputStream; import java ...