LeetCode 591. Tag Validator(java)

Given a string representing a code snippet, you need to implement a tag validator to parse the code and return whether it is valid. A code snippet is valid if all the following rules hold:

The code must be wrapped in a valid closed tag. Otherwise, the code is invalid.
A closed tag (not necessarily valid) has exactly the following format : TAG_CONTENT. Among them, is the start tag, and is the end tag. The TAG_NAME in start and end tags should be the same. A closed tag is valid if and only if the TAG_NAME and TAG_CONTENT are valid.
A valid TAG_NAME only contain upper-case letters, and has length in range [1,9]. Otherwise, the TAG_NAME is invalid.
A valid TAG_CONTENT may contain other valid closed tags, cdata and any characters (see note1) EXCEPT unmatched <, unmatched start and end tag, and unmatched or closed tags with invalid TAG_NAME. Otherwise, the TAG_CONTENT is invalid.
A start tag is unmatched if no end tag exists with the same TAG_NAME, and vice versa. However, you also need to consider the issue of unbalanced when tags are nested.
A < is unmatched if you cannot find a subsequent >. And when you find a < or


Input: "<DIV>>>  ![cdata[]] <![CDATA[<div>]>]]>]]>>]</DIV>"

Output: True

Explanation:

We first separate the code into : start_tag|tag_content|end_tag.

start_tag -> "<DIV>"

end_tag -> "</DIV>"

tag_content could also be separated into : text1|cdata|text2.

text1 -> ">>  ![cdata[]] "

cdata -> "<![CDATA[<div>]>]]>", where the CDATA_CONTENT is "<div>]>"

text2 -> "]]>>]"


The reason why start_tag is NOT "<DIV>>>" is because of the rule 6.
The reason why cdata is NOT "<![CDATA[<div>]>]]>]]>" is because of the rule 7.
Invalid Code Examples:
Input: "<A>  <B> </A>   </B>"
Output: False
Explanation: Unbalanced. If "<A>" is closed, then "<B>" must be unmatched, and vice versa.

Input: "<DIV>  div tag is not closed  <DIV>"
Output: False

Input: "<DIV>  unmatched <  </DIV>"
Output: False

Input: "<DIV> closed tags with invalid tag name  <b>123</b> </DIV>"
Output: False

Input: "<DIV> unmatched tags with invalid tag name  </1234567890> and <CDATA[[]]>  </DIV>"
Output: False

Input: "<DIV>  unmatched start tag <B>  and unmatched end tag </C>  </DIV>"
Output: False

Note:
For simplicity, you could assume the input code (including the any characters mentioned above) only contain letters, digits, ‘<’,’>’,’/’,’!’,’[‘,’]’ and ’ ‘.

一道很繁琐的题目,主要是需要用对数据结构。
class Solution {
    public static boolean isValid(String code) {
        //special case
        if (code.length() == 0) return false;
        //general case
        if (code.charAt(0) != '<') return false;
        Stack<String> stack = new Stack<String>();
        int i = 0;
        while (i < code.length()) {
            if (i > 0 && stack.isEmpty()) return false;
            if (code.startsWith("<![CDATA[", i)) {
                int end = code.indexOf("]]>", i + 9);
                if (end == -1) return false;
                i = end + 3;
            } else if (code.startsWith("</", i)) {
                int end = code.indexOf(">", i + 2);
                if (end == -1 || end == i + 2 || end - i - 2 > 9) return false;
                String s = code.substring(i + 2, end);
                for (int j = 0; j < s.length(); j++) {
                    if (s.charAt(j) > 'Z' || s.charAt(j) < 'A') return false;
                }
                if (stack.isEmpty() || !stack.pop().equals(s)) return false;
                i = end + 1;
            } else if (code.startsWith("<", i)) {
                int end = code.indexOf(">", i + 1);
                if (end == -1 || end == i + 1 || end - i - 1 > 9) return false;
                String s = code.substring(i + 1, end);
                for (int j = 0; j < s.length(); j++) {
                    if (s.charAt(j) > 'Z' || s.charAt(j) < 'A') return false;
                }
                stack.push(s);
                i = end + 1;
            } else {
                i++;
            }
        }
        return stack.isEmpty() ? true : false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值