leetcode
leetcode 501 ~ 550
标签验证器

标签验证器

难度:

标签:

题目描述

代码结果

运行时间: 28 ms, 内存: 16.2 MB


/*
题目思路:
1. 使用Java Stream流来处理字符串的拆分与匹配检查。
2. 分别处理起始标签、结束标签和CDATA内容。
3. 使用栈结构存储起始标签,结束时进行匹配。
4. CDATA部分不需要检查其内容的合法性。
*/
 
import java.util.Stack;
 
public class Solution {
    public boolean isValid(String code) {
        if (code == null || code.isEmpty()) return false;
        Stack<String> stack = new Stack<>();
        int i = 0;
        while (i < code.length()) {
            if (code.startsWith("<![CDATA[", i)) {
                int j = i + 9;
                i = code.indexOf("]]>", j);
                if (i < 0) return false;
                i += 3;
            } else if (code.startsWith("</", i)) {
                int j = i + 2;
                i = code.indexOf('>', j);
                if (i < 0 || i == j) return false;
                String tagName = code.substring(j, i);
                if (stack.isEmpty() || !stack.pop().equals(tagName)) return false;
                i++;
            } else if (code.startsWith("<", i)) {
                int j = i + 1;
                i = code.indexOf('>', j);
                if (i < 0 || i == j || i - j > 9) return false;
                String tagName = code.substring(j, i);
                if (!tagName.matches("[A-Z]+")) return false;
                stack.push(tagName);
                i++;
            } else {
                i++;
            }
        }
        return stack.isEmpty();
    }
}

解释

方法:

这个题解使用栈来验证代码的合法性。遍历整个代码字符串,遇到开始标签时入栈,遇到结束标签时判断是否与栈顶标签匹配并出栈。同时需要处理 CDATA 标签和一些特殊情况。最后判断栈是否为空,为空则代码合法,否则不合法。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在处理CDATA部分时,如果CDATA标签内部包含了伪造的闭合标签如`]]>`,该如何确保算法不会错误地识别结束点?
在算法中,当遇到`', i)`来查找CDATA区段的结束点。在这种情况下,即使CDATA内容中包含伪造的`]]>`,`find`方法会返回第一个出现的`]]>`的位置。因此,这里的关键是如何处理CDATA内的数据。理论上,CDATA区块允许包含任何字符,包括`]]>`,但是在实际处理中,一旦检测到第一个`]]>`序列,算法就会认定CDATA区块结束。为了更准确处理,可以通过在CDATA区块中逐字符检查,直到遇到确切无误的闭合标签`]]>`,但这会增加算法的复杂度。当前算法假定输入是合理的,不包含误导性的CDATA结束标签。
🦆
函数`isValidTagName`中验证标签名称是否为大写的条件为何与长度检查分开,这是否有特殊的原因或优化?
函数`isValidTagName`中的标签名验证逻辑首先检查标签名是否全部由大写字母组成,然后检查其长度是否在1到9之间。这种分开处理主要是为了清晰地区分不同的验证规则,并且让错误类型更容易被理解和调试。例如,如果一个标签名由数字组成,那么首先违反的是“必须由字母组成”的规则,而不是长度规则。通过分开检查,可以更精确地提供错误反馈,告诉用户具体是哪部分的验证失败了。这种方法也有利于代码的可维护性和可读性。
🦆
在遇到非法标签时,算法是直接返回`False`,那么是否有可能存在某些情况下应该继续解析剩余字符串以检查其他可能的错误?
在当前的算法实现中,一旦遇到非法标签或其他验证失败的情况,就直接返回`False`,这意味着整个字符串不符合要求。这种设计选择是基于效率和实用性的考虑。虽然在某些应用场景中,继续解析以识别所有可能的错误可以提供更详细的错误信息,但在这种情况下,目标是尽快确认字符串是否完全有效。继续解析可能会导致算法效率降低,特别是在处理很长的字符串时。如果需要详尽的错误报告,可以设计一个更复杂的解析器,不仅检查合法性,还能收集所有的错误详情。

相关问题

给字符串添加加粗标签

给字符串添加加粗标签