BL11. 实现一个HTML语法检查器
描述
实现一个HTML语法检查器。HTML语法规则简化如下:标签必须闭合,可以由开始和结束两个标签闭合,如<div></div>,也可以自闭合,输入描述
一行,一个HTML字符串输出描述
有语法错误返回1,没有语法错误返回0示例1
输入:
<div><a></a></div>
输出:
0
示例2
输入:
<div><a></div></a>
输出:
1
C++ 解法, 执行用时: 2ms, 内存消耗: 488KB, 提交时间: 2020-08-21
#include <iostream> #include <string> #include <stack> using namespace std; //判断是否为属性 int isPro(string str, int& i) { if (str[i] >= 'a'&&str[i] <= 'z') { while (str[i] >= 'a'&&str[i] <= 'z') i++; while (str[i] == ' ') i++; if (str[i] == '=') { while (str[++i] == ' '); if (str[i] == '\"') { ++i; while (str[i] != '"' && i < str.size()) i++; if (str[i] == '"') //可能是属性 { if(str[i] == ' ') return 0; else { while (str[i+1] != ' ' && str[i+1] != '<' && str[i+1] != '/' && str[i+1] != '>' && str[i+1] != '\0') { if (str[++i] == '=') return 1; } return 0; } } } } else if(str[i] == '/' || str[i] == '>' || str[i] == '<' || str[i] == '\0'|| (str[i] >= 'a' && str[i] <= 'z')) { i--; return 0; } } return 1; //不符合属性格式要求,返回1 } //判断是否为标签 int isTag(string str, int& i, stack<string>& ss) { if (str[i++] == '<') { //标签名 string tagName; //判断是否为字母 if (str[i] >= 'a'&&str[i] <= 'z') //可能是起始标签 { while (str[i] >= 'a'&&str[i] <= 'z') { tagName += str[i++]; } while (str[i] == ' ') i++; //跳过空格 if (str[i] >= 'a' && str[i] <= 'z') //可能是属性 { if (isPro(str, i)) //判断标签内是否带有属性 { return 1; } else //有属性,跳过全部属性 { i++; while (str[i] == ' ') i++; while (str[i] >= 'a'&&str[i] <= 'z') { if (isPro(str, i)) return 1; while (str[++i] == ' '); } } if (str[i] == '>') //起始标签 { ss.push(tagName); return 0; } else if (str[i] == '/' && str[i+1] == '>') //自闭标签 { ++i; return 0; } } else if (str[i] == '/') //可能是自闭标签 { return (str[++i] == '>') ? 0:1; } else if (str[i] == '>') //起始标签 { ss.push(tagName); return 0; } } else if (str[i] == '/' && !ss.empty() && ss.top()[0] != '/') //结束标签 { i++; if (str[i] >= 'a'&&str[i] <= 'z') { while (str[i] >= 'a'&&str[i] <= 'z') { tagName += str[i++]; } //跳过空格 while (str[i] == ' ') i++; if (str[i] == '>' && tagName == ss.top()) { ss.pop(); return 0; } } } } //不是标签 return 1; } //判断是否符合 int check(string str) { stack<string> ss; //判断是否为标签 for (int i = 0;i < str.size();++i) { //跳过空格 while (str[i] == ' ') i++; if (str[i] == '<') { if (isTag(str, i, ss)) return 1; } else if ((str[i] >= 'a'&&str[i] <= 'z'))// && !ss.empty()) { if (isPro(str, i)) return 1; } else if (str[i] != '"') { return 1; } } return ss.empty() ? 0:1; } int main(int argc, char** argv) { string str; getline(cin, str); cout << check(str) << endl; return 0; }
C++14 解法, 执行用时: 2ms, 内存消耗: 504KB, 提交时间: 2019-08-21
#include <iostream> #include <string> #include <stack> using namespace std; //判断是否为属性 int isPro(string str, int& i) { if (str[i] >= 'a'&&str[i] <= 'z') { while (str[i] >= 'a'&&str[i] <= 'z') i++; while (str[i] == ' ') i++; if (str[i] == '=') { while (str[++i] == ' '); if (str[i] == '\"') { ++i; while (str[i] != '"' && i < str.size()) i++; if (str[i] == '"') //可能是属性 { if(str[i] == ' ') return 0; else { while (str[i+1] != ' ' && str[i+1] != '<' && str[i+1] != '/' && str[i+1] != '>' && str[i+1] != '\0') { if (str[++i] == '=') return 1; } return 0; } } } } else if(str[i] == '/' || str[i] == '>' || str[i] == '<' || str[i] == '\0'|| (str[i] >= 'a' && str[i] <= 'z')) { i--; return 0; } } return 1; //不符合属性格式要求,返回1 } //判断是否为标签 int isTag(string str, int& i, stack<string>& ss) { if (str[i++] == '<') { //标签名 string tagName; //判断是否为字母 if (str[i] >= 'a'&&str[i] <= 'z') //可能是起始标签 { while (str[i] >= 'a'&&str[i] <= 'z') { tagName += str[i++]; } while (str[i] == ' ') i++; //跳过空格 if (str[i] >= 'a' && str[i] <= 'z') //可能是属性 { if (isPro(str, i)) //判断标签内是否带有属性 { return 1; } else //有属性,跳过全部属性 { i++; while (str[i] == ' ') i++; while (str[i] >= 'a'&&str[i] <= 'z') { if (isPro(str, i)) return 1; while (str[++i] == ' '); } } if (str[i] == '>') //起始标签 { ss.push(tagName); return 0; } else if (str[i] == '/' && str[i+1] == '>') //自闭标签 { ++i; return 0; } } else if (str[i] == '/') //可能是自闭标签 { return (str[++i] == '>') ? 0:1; } else if (str[i] == '>') //起始标签 { ss.push(tagName); return 0; } } else if (str[i] == '/' && !ss.empty() && ss.top()[0] != '/') //结束标签 { i++; if (str[i] >= 'a'&&str[i] <= 'z') { while (str[i] >= 'a'&&str[i] <= 'z') { tagName += str[i++]; } //跳过空格 while (str[i] == ' ') i++; if (str[i] == '>' && tagName == ss.top()) { ss.pop(); return 0; } } } } //不是标签 return 1; } //判断是否符合 int check(string str) { stack<string> ss; //判断是否为标签 for (int i = 0;i < str.size();++i) { //跳过空格 while (str[i] == ' ') i++; if (str[i] == '<') { if (isTag(str, i, ss)) return 1; } else if ((str[i] >= 'a'&&str[i] <= 'z'))// && !ss.empty()) { if (isPro(str, i)) return 1; } else if (str[i] != '"') { return 1; } } return ss.empty() ? 0:1; } int main(int argc, char** argv) { string str; getline(cin, str); cout << check(str) << endl; return 0; }
C++ 解法, 执行用时: 3ms, 内存消耗: 388KB, 提交时间: 2021-03-25
#include<bits/stdc++.h> using namespace std; int main(){ string s; getline(cin,s); if(s.back()!='>'){ cout<<1; return 0; } stack<string> st; string str=""; bool flag=false; //是否需要记录 bool zibihe=false; bool yinhao=false; for(int i=0;i<s.length();i++){ // cout<<i<<" "; if(s[i]=='"' && s[i-1]=='='){ yinhao=true; }else if(s[i]=='"' && yinhao){ yinhao=false; } if(yinhao){ continue; } if(s[i]=='<'){ if(str!=""){ if(!st.empty() && st.top()==str){ st.pop(); }else { //cout<<str<<endl; st.push(str); } } str=""; flag=true; }else if(s[i]=='/'){ if(s[i-1]!='<'){ //<div/>自闭和的情况 str=""; flag=false; zibihe=true; } }else if(s[i]=='>'){ //cout<<">"<<str<<endl; if(!zibihe){ //查看栈中的元素是否为str if(!st.empty() && st.top()==str){ st.pop(); }else { //cout<<str<<endl; st.push(str); } str=""; flag=false; }else{ zibihe=false; } }else if(s[i]==' '){ flag=false; }else{ if(flag){ str.push_back(s[i]); } } } if(st.empty()){ cout<<0; }else{ cout<<1; } return 0; }
C++14 解法, 执行用时: 3ms, 内存消耗: 476KB, 提交时间: 2020-05-20
#include <iostream> #include <string> #include <stack> using namespace std; //判断是否为属性 int isPro(string str, int& i) { if (str[i] >= 'a'&&str[i] <= 'z') { while (str[i] >= 'a'&&str[i] <= 'z') i++; while (str[i] == ' ') i++; if (str[i] == '=') { while (str[++i] == ' '); if (str[i] == '\"') { ++i; while (str[i] != '"' && i < str.size()) i++; if (str[i] == '"') //可能是属性 { if(str[i] == ' ') return 0; else { while (str[i+1] != ' ' && str[i+1] != '<' && str[i+1] != '/' && str[i+1] != '>' && str[i+1] != '\0') { if (str[++i] == '=') return 1; } return 0; } } } } else if(str[i] == '/' || str[i] == '>' || str[i] == '<' || str[i] == '\0'|| (str[i] >= 'a' && str[i] <= 'z')) { i--; return 0; } } return 1; //不符合属性格式要求,返回1 } //判断是否为标签 int isTag(string str, int& i, stack<string>& ss) { if (str[i++] == '<') { //标签名 string tagName; //判断是否为字母 if (str[i] >= 'a'&&str[i] <= 'z') //可能是起始标签 { while (str[i] >= 'a'&&str[i] <= 'z') { tagName += str[i++]; } while (str[i] == ' ') i++; //跳过空格 if (str[i] >= 'a' && str[i] <= 'z') //可能是属性 { if (isPro(str, i)) //判断标签内是否带有属性 { return 1; } else //有属性,跳过全部属性 { i++; while (str[i] == ' ') i++; while (str[i] >= 'a'&&str[i] <= 'z') { if (isPro(str, i)) return 1; while (str[++i] == ' '); } } if (str[i] == '>') //起始标签 { ss.push(tagName); return 0; } else if (str[i] == '/' && str[i+1] == '>') //自闭标签 { ++i; return 0; } } else if (str[i] == '/') //可能是自闭标签 { return (str[++i] == '>') ? 0:1; } else if (str[i] == '>') //起始标签 { ss.push(tagName); return 0; } } else if (str[i] == '/' && !ss.empty() && ss.top()[0] != '/') //结束标签 { i++; if (str[i] >= 'a'&&str[i] <= 'z') { while (str[i] >= 'a'&&str[i] <= 'z') { tagName += str[i++]; } //跳过空格 while (str[i] == ' ') i++; if (str[i] == '>' && tagName == ss.top()) { ss.pop(); return 0; } } } } //不是标签 return 1; } //判断是否符合 int check(string str) { stack<string> ss; //判断是否为标签 for (int i = 0;i < str.size();++i) { //跳过空格 while (str[i] == ' ') i++; if (str[i] == '<') { if (isTag(str, i, ss)) return 1; } else if ((str[i] >= 'a'&&str[i] <= 'z'))// && !ss.empty()) { if (isPro(str, i)) return 1; } else if (str[i] != '"') { return 1; } } return ss.empty() ? 0:1; } int main(int argc, char** argv) { string str; getline(cin, str); cout << check(str) << endl; return 0; }
C++ 解法, 执行用时: 3ms, 内存消耗: 480KB, 提交时间: 2019-08-15
#include <iostream> #include <string> #include <stack> using namespace std; //判断是否为属性 int isPro(string str, int& i) { if (str[i] >= 'a'&&str[i] <= 'z') { while (str[i] >= 'a'&&str[i] <= 'z') i++; while (str[i] == ' ') i++; if (str[i] == '=') { while (str[++i] == ' '); if (str[i] == '\"') { ++i; while (str[i] != '"' && i < str.size()) i++; if (str[i] == '"') //可能是属性 { if(str[i] == ' ') return 0; else { while (str[i+1] != ' ' && str[i+1] != '<' && str[i+1] != '/' && str[i+1] != '>' && str[i+1] != '\0') { if (str[++i] == '=') return 1; } return 0; } } } } else if(str[i] == '/' || str[i] == '>' || str[i] == '<' || str[i] == '\0'|| (str[i] >= 'a' && str[i] <= 'z')) { i--; return 0; } } return 1; //不符合属性格式要求,返回1 } //判断是否为标签 int isTag(string str, int& i, stack<string>& ss) { if (str[i++] == '<') { //标签名 string tagName; //判断是否为字母 if (str[i] >= 'a'&&str[i] <= 'z') //可能是起始标签 { while (str[i] >= 'a'&&str[i] <= 'z') { tagName += str[i++]; } while (str[i] == ' ') i++; //跳过空格 if (str[i] >= 'a' && str[i] <= 'z') //可能是属性 { if (isPro(str, i)) //判断标签内是否带有属性 { return 1; } else //有属性,跳过全部属性 { i++; while (str[i] == ' ') i++; while (str[i] >= 'a'&&str[i] <= 'z') { if (isPro(str, i)) return 1; while (str[++i] == ' '); } } if (str[i] == '>') //起始标签 { ss.push(tagName); return 0; } else if (str[i] == '/' && str[i+1] == '>') //自闭标签 { ++i; return 0; } } else if (str[i] == '/') //可能是自闭标签 { return (str[++i] == '>') ? 0:1; } else if (str[i] == '>') //起始标签 { ss.push(tagName); return 0; } } else if (str[i] == '/' && !ss.empty() && ss.top()[0] != '/') //结束标签 { i++; if (str[i] >= 'a'&&str[i] <= 'z') { while (str[i] >= 'a'&&str[i] <= 'z') { tagName += str[i++]; } //跳过空格 while (str[i] == ' ') i++; if (str[i] == '>' && tagName == ss.top()) { ss.pop(); return 0; } } } } //不是标签 return 1; } //判断是否符合 int check(string str) { stack<string> ss; //判断是否为标签 for (int i = 0;i < str.size();++i) { //跳过空格 while (str[i] == ' ') i++; if (str[i] == '<') { if (isTag(str, i, ss)) return 1; } else if ((str[i] >= 'a'&&str[i] <= 'z'))// && !ss.empty()) { if (isPro(str, i)) return 1; } else if (str[i] != '"') { return 1; } } return ss.empty() ? 0:1; } int main(int argc, char** argv) { string str; getline(cin, str); cout << check(str) << endl; return 0; }