classSolution{public:boolisValid(stringcode){if(code[0]!='<'||code.back()!='>')returnfalse;stack<string>stack;for(inti=0;i<code.length();++i){intcloseIndex=0;if(stack.empty()&&containsTag)returnfalse;if(code[i]=='<'){// Inside a tag, so we can check if it's a cdataif(!stack.empty()&&code[i+1]=='!'){closeIndex=code.find("]]>",i+2);if(closeIndex==string::npos||!isValidCdata(code.substr(i+2,closeIndex-i-2)))returnfalse;}elseif(code[i+1]=='/'){// End tagcloseIndex=code.find('>',i+2);if(closeIndex==string::npos||!isValidTagName(stack,code.substr(i+2,closeIndex-i-2),true))returnfalse;}else{// Start tagcloseIndex=code.find('>',i+1);if(closeIndex==string::npos||!isValidTagName(stack,code.substr(i+1,closeIndex-i-1),false))returnfalse;}i=closeIndex;}}returnstack.empty()&&containsTag;}private:boolcontainsTag=false;boolisValidCdata(conststring&s){returns.find("[CDATA[")==0;}boolisValidTagName(stack<string>&stack,conststring&tagName,boolisEndTag){if(tagName.empty()||tagName.length()>9)returnfalse;for(constcharc:tagName)if(!isupper(c))returnfalse;if(isEndTag){if(stack.empty())returnfalse;if(stack.top()!=tagName)returnfalse;stack.pop();returntrue;}containsTag=true;stack.push(tagName);returntrue;}};
classSolution{publicbooleanisValid(Stringcode){if(code.charAt(0)!='<'||code.charAt(code.length()-1)!='>')returnfalse;Deque<String>stack=newArrayDeque<>();for(inti=0;i<code.length();++i){intcloseIndex=0;if(stack.isEmpty()&&containsTag)returnfalse;if(code.charAt(i)=='<'){// Inside a tag, so we can check if it's a cdataif(!stack.isEmpty()&&code.charAt(i+1)=='!'){closeIndex=code.indexOf("]]>",i+2);if(closeIndex<0||!isValidCdata(code.substring(i+2,closeIndex)))returnfalse;}elseif(code.charAt(i+1)=='/'){// End tagcloseIndex=code.indexOf('>',i+2);if(closeIndex<0||!isValidTagName(stack,code.substring(i+2,closeIndex),true))returnfalse;}else{// Start tagcloseIndex=code.indexOf('>',i+1);if(closeIndex<0||!isValidTagName(stack,code.substring(i+1,closeIndex),false))returnfalse;}i=closeIndex;}}returnstack.isEmpty()&&containsTag;}privatebooleancontainsTag=false;privatebooleanisValidCdata(finalStrings){returns.indexOf("[CDATA[")==0;}privatebooleanisValidTagName(Deque<String>stack,StringtagName,booleanisEndTag){if(tagName.isEmpty()||tagName.length()>9)returnfalse;for(finalcharc:tagName.toCharArray())if(!Character.isUpperCase(c))returnfalse;if(isEndTag)return!stack.isEmpty()&&stack.pop().equals(tagName);containsTag=true;stack.push(tagName);returntrue;}}
classSolution:defisValid(self,code:str)->bool:ifcode[0]!='<'orcode[-1]!='>':returnFalsecontainsTag=Falsestack=[]defisValidCdata(s:str)->bool:returns.find('[CDATA[')==0defisValidTagName(tagName:str,isEndTag:bool)->bool:nonlocalcontainsTagifnottagNameorlen(tagName)>9:returnFalseifany(notc.isupper()forcintagName):returnFalseifisEndTag:returnstackandstack.pop()==tagNamecontainsTag=Truestack.append(tagName)returnTruei=0whilei<len(code):ifnotstackandcontainsTag:returnFalseifcode[i]=='<':# Inside a tag, so we can check if it's a cdataifstackandcode[i+1]=='!':closeIndex=code.find(']]>',i+2)ifcloseIndex==-1ornotisValidCdata(code[i+2:closeIndex]):returnFalseelifcode[i+1]=='/':# End tagcloseIndex=code.find('>',i+2)ifcloseIndex==-1ornotisValidTagName(code[i+2:closeIndex],True):returnFalseelse:# Start tagcloseIndex=code.find('>',i+1)ifcloseIndex==-1ornotisValidTagName(code[i+1:closeIndex],False):returnFalsei=closeIndexi+=1returnnotstackandcontainsTag