您的位置:首页 > 其它

[ZOJ 1116 ] [ POJ 1911 ] A Well-Formed Problem

2011-07-03 14:10 495 查看
ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1116
题目大意:
(对XML没有了解,只是按照字面意思理解了一下题意)
<name>与</name>这样有起始结束声明的,name称为tag
<order/>是empty element, 不需要end-tag
第一行<?xml version="1.0"?>不算文档的element
<zip-code format="PLUS4">10001-0001</zip-code>这里的format是zip-code的属性
一个well-formed document要满足下面几条:
1、只有一个element不嵌套在别的element里,例如例子中的"customer"
2、嵌套正确,不是<order/>那样的,如<name>与</name>要完整配对嵌套
3、如<name>与</name>这样的声明名字要配对
4、一个tag最多一个属性
5、不递归调用,如address element里不能调用address
6、有名字的属性,比如上面的format,要有对应的值
注意大小写不同,如<Address>和<address>应该认为是不同的

输入:

每组数据第一行是 "<?xml version="1.0"?>"。
"<?end?>" 表示全部输入的结束(只是在本题中用来标记输入结束)
输入保证:
"<?xml version="1.0"?>"会且仅会在第一行出现
element和属性只用数字、字母和短线"-"表示
XML注释不出现
属性的值一定会放在“”里

输出

"well-formed"或者"non well-formed"

解题思路:
字符串处理,主要用到栈和集合。
每次读入到”<“的时候,开始读取tag和attribute,同时判断<>里头的内容有没有问题,比如"/"出现的位置和次数有没有问题,属性的表达有没有问题等。之后就只要进行一些判断即可。下面是针对well-formed document的各条件的解决方法:
1、针对“只有一个element不嵌套在别的element里,例如例子中的"customer" ”
设置bool root=false; 当栈空且有入栈操作时root=true;当root=true且在栈空情况下有入栈操作时返回non well-formed
2、针对“嵌套正确,不是<order/>那样的,如<name>与</name>要完整配对嵌套”
栈,非类似<order/>时入栈,入栈忽略属性,出栈时与栈顶元素
3、针对“如<name>与</name>这样的声明名字要配对”
同上
4、针对“一个tag最多一个属性”
若在<>里读到""(输入保证如果有属性,其值一定包括在""里), 则之后如果再出现非空字符,返回non well-formed
5、针对“不递归调用,如address element里不能调用address”
设置set<string>类型,存放栈内元素,入栈前判断set里是否有相同tag,如果是,返回non well-formed
6、针对“有名字的属性,比如上面的format,要有对应的值”
在<>内如果读到空格,空格后面有字符,则必须有紧跟的="XXX"

源代码:
又吐血了……”狗狗搞完40题“里的代码又好短,泪奔了,为什么每次写蘑菇题我都要写得很长╮(╯▽╰)╭
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <string>
#include <set>
#include <stack>
#include <iostream>
#include <algorithm>
using namespace std;
#define ERROR non=true;return

set<string> used;
stack<string> s;
bool non, root;

bool gettag(char* &ch, string &tag, bool &end, bool &empty)
// 读到"<"触发gettag, 函数结束后">"已读过
{
int p1, p2, p3, p4;
string attribute;

end=false, empty=false;
tag=attribute="";

ch++;                                   //get tag
if (*ch=='/'){end=true;ch++;}
while (isalnum(*ch) || *ch=='-')
{
tag+=*ch;
ch++;
}
while (isspace(*ch)) ch++;
if (*ch=='>')                            //end of tag?
return 1;
if (*ch=='/')
{
int cal=0;
ch++;
while (*ch!='>'){cal++;ch++;}
if (cal>0) return -2;
if (end) return -1;
else empty=true;
}
while (isalnum(*ch) || *ch=='-' || *ch=='.' || *ch=='\"' || *ch=='=')        //get attribute
{
attribute+=*ch;
ch++;
}
if (attribute.length()>0)
{
p1=attribute.find("=", 0);      if (p1==-1) return -3;
p2=attribute.find("\"", 0);     if (p2<p1) return -4;
p2=attribute.find("\"", p1+1);  if (p2==-1) return -5;
p3=attribute.find("\"", p2+1);  if (p3==-1 || p3==p2+1) return -6;   //empty value
p4=attribute.find("\"", p3+1);  if (p4!=-1) return -7;               //extra "
p4=attribute.find("=", p1+1);   if (p4!=-1) return -8;               //extra =
}
while (isspace(*ch)) ch++;
if (*ch=='>') return 1;
if (*ch=='/')
{
int cal=0;
ch++;
while (*ch!='>'){cal++;ch++;}
if (cal>0) return -10;
if (end) return -9;
else empty=true;
}
while (*ch!='>'){
ch++;
if (!isspace(*ch) && *ch!='>') return -11;
}
return 1;
}

void solve(char *ch)
{
bool end, empty;
string tag;
int tmp;
while (!non && *ch!='\0')
{
if (*ch=='<')
{
tmp=gettag(ch, tag, end, empty);
if (tmp==1)
{
if (end && empty){
ERROR;
}
if (empty && used.count(tag)>0){
ERROR;
}
else if (!empty && !end)
{
if (used.count(tag)>0){
ERROR;
}
if (s.empty())
{
if (root){ERROR;}
else root=true;
}
used.insert(tag);
s.push(tag);
}
else if (!empty && end)
{
if (s.empty() || s.top()!=tag){
ERROR;
}
used.erase(tag);
s.pop();
}
}
else{ERROR;}
}
else ch++;
}
}

int main()
{
string tag, attribute;
bool firstdata=true;
bool end, empty;
char buf[65536];
do{
while (gets(buf)!=NULL && strcmp(buf, "<?xml version=\"1.0\"?>")!=0
&& strcmp(buf, "<?end?>\n")!=0)
{
solve(buf);
}
if (strcmp(buf, "<?xml version=\"1.0\"?>")==0)
{
if (!firstdata)
{
if (non || !s.empty()) printf("non well-formed\n");
else printf("well-formed\n");
}
else firstdata=false;
non=false;
root=false;
used.clear();
while (!s.empty()) s.pop();
}
}while (strcmp(buf, "<?end?>")!=0);
if (non || !s.empty()) printf("non well-formed\n");
else printf("well-formed\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: