题目:http://poj.org/problem?id=2022
分析:只有3种子节点,只需让每个节点【开闭】统一即可
#include <stdio.h>
#include <string.h>
#include <string>
#include <stack>
using namespace std;
enum{ERROR, WAIT_FOR_LEFT, WAIT_FOR_RIGHT};
bool check(const string& attr, stack<string>& attrStack)
{
// printf("check %s\n", attr.c_str());
if(attr.empty()){
return false;
}
if(attr[0] == '/'){
if(attr.size() != 2) return false;
if(attrStack.empty() || attr.substr(1, 1) != attrStack.top()) return false;
attrStack.pop();
}
else{
if(attr == "B" || attr == "I") attrStack.push(attr);
else if(attr[0] == 'A'){
size_t pos = attr.find('=');
if(pos == string::npos) return false;
if(attr.substr(0, pos) != "A HREF") return false;
//check if url = "http://STRING.com"
const string& url = attr.substr(pos+1);
const char* p = url.c_str();
int len = url.size();
const char uh[] = "http://", ut[] = ".com";
int hlen = sizeof(uh)/sizeof(char) - 1, tlen = sizeof(ut)/sizeof(char) - 1;
if(len < hlen + tlen) return false;
if(strncmp(p, uh, hlen) != 0 || strncmp(p+len-tlen, ut, tlen) != 0) return false;
if(string(p+hlen, len-hlen-tlen).find_first_of("<>") != string::npos) return false;
attrStack.push("A");
}
else return false;
}
return true;
}
bool test(char* s, char* e)
{
// printf("test [%s]\n", string(s, e-s).c_str());
string attr;
stack<string> st;
int state = WAIT_FOR_LEFT;
while(s < e){
char c = *s++;
if(state == WAIT_FOR_LEFT){
if(c == '<'){
state = WAIT_FOR_RIGHT;
attr.clear();
}
else if(c == '>'){
state = ERROR;
break;
}
}
else{
if(c == '>'){
if(!check(attr, st)){
state = ERROR;
break;
}
state = WAIT_FOR_LEFT;
}
else if(c == '<'){
state = ERROR;
break;
}
else{
attr.push_back(c);
}
}
}
return state == WAIT_FOR_LEFT && st.empty();
}
int main()
{
char s[1024], h[] = "<HTML><BODY>", t[] = "</BODY></HTML>";
int n, slen, hlen = sizeof(h)/sizeof(char) - 1, tlen = sizeof(t)/sizeof(char) - 1;
scanf("%d", &n);
while(getchar() != '\n') ;
while(n--){
bool ok = false;
slen = strlen(gets(s));
if(slen >= hlen + tlen){
if(strncmp(s, h, hlen) == 0 && strncmp(s + slen - tlen, t, tlen) == 0){
ok = test(s + hlen, s + slen - tlen);
}
}
puts(ok ? "Syntax Included" : "No Syntax Included");
}
return 0;
}