看到这道题时我的内心是奔溃的,没有了解过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. CGroup 介绍、应用实例及原理描述

    CGroup 介绍 CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制.记录.隔离进程组 (process groups) 所使用的物力资源 (如 cpu ...

  2. WinXP系统服务详细列表

    windows XP 系统服务“关闭”详细列表,释放N多内存,128也够用了! 在xp系统中,有近90个服务,默认开启了 30多个服务,而事实上我们只需要其中几个就够用了.禁止所有不必要的服务可以为您 ...

  3. 编译原理Tiny语言的定义

    Here is the definition for Tiny language The Tiny lexicon is as follows: Keywords:   IF ELSE WRITE R ...

  4. 用Chart控件绘制动态图表

    进行程序设计时,选用一个合适的ActiveX控件,有时可大大减少编程工作量.ActiveX 控件(又称OCX)基于COM技术,作为独立的软件模块,它可以在任何程序设计语言中插入使用.本文仅以VC++为 ...

  5. android之IntentFilter的用法_Intent.ACTION_TIME_TICK在manifest.xml不起作用

    在模仿一个天气预报的widget时候,用到了IntentFilter,感觉在manifest.xml注册的receiver跟用代码写registerReceiver()的效果应该是相同的,于是想证明一 ...

  6. Storm 配置图文解析

    Storm 配置图文解析 參考阅读:http://www.xiaofateng.com/? p=959 ============================== | sample-topology ...

  7. 为学Linux,我看了这些书

    为学Linux,我看了这些书   去年开始,抱着学习的态度开始了我的Linux学习,到现在,差不多一年了,收获很多,不敢说精通Linux,但是,还是对得起"略懂"这两个字的.这一年 ...

  8. hibernate 一对多映射

    package com.entity.onetomany; import java.util.ArrayList; import java.util.List; import javax.persis ...

  9. Android 程式开发:(廿一)消息传递 —— 21.3 使用Intent发送短信

    使用SmsManager类,可以在自己编写的程序内部发送短信,而不需要调用系统的短信应用. 然而,有的时候调用系统内置的短信应用会更加方便. 这时,需要使用一个MIME类型为vnd.android-d ...

  10. HTTP的请求头标签If-Modified-Since

    一直以来没有留意过HTTP请求头的IMS(If-Modified-Since)标签. 最近在分析Squid的access.log日志文件时,发现了一个现象. 就是即使是对同一个文件进行HTTP请求,第 ...