【问题标题】:finding validity of bracket string in java在java中查找括号字符串的有效性
【发布时间】:2016-04-09 11:52:11
【问题描述】:

事情是这样的:

给你一个字符串,其元素是方括号( ) [ ] { }

规则:

  1. 每个左括号都有一个对应的右括号。

  2. 如果两个括号之间没有任何类型的左括号,则它们形成一对。

  3. 一对的右括号必须与左括号相同,例如() 有效,但[) 无效。

任务是根据这些标准确定括号字符串是否有效。

示例有效字符串:{}[]()

无效字符串示例:{[}]

这是我的解决方案:

static String braces(String string) {
   Stack<String> stack = new Stack<>();
   for(int i = 0; i <= string.length() - 1; i ++){

       if(string.substring(i, i+1).equals("("))
           stack.push((string.substring(i, i+1)));

       else if(string.substring(i, i+1).equals("["))
           stack.push((string.substring(i, i+1)));

       else if(string.substring(i, i+1).equals("{"))
           stack.push((string.substring(i, i+1)));

       else if(string.substring(i, i+1).equals(")"))
           if(stack.peek().equals("("))
               stack.pop();
           else
               return "NO";

       else if(string.substring(i, i+1).equals("]"))
           if(stack.peek().equals("["))
               stack.pop();
           else
               return "NO";

       else if(string.substring(i, i+1).equals("}"))
           if(stack.peek().equals("{"))
               stack.pop();
           else 
               return "NO";
       }
   return "YES";
   }

根据How to find validity of a string of parentheses, curly brackets and square brackets?的算法完成,如下:

  1. 维护一堆字符。
  2. 每当您发现左大括号 '('、'{' 或 '[' 时,将其推到 堆栈。
  3. 每当您发现右大括号 ')'、'}' 或 ']' 时,检查顶部是否 stack 是对应的左括号,如果是,则弹出堆栈, else 打破循环并返回 false。
  4. 重复步骤 2 - 3 直到字符串结束。

但我不喜欢它的样子。访问 String 元素的方式有点笨拙,我很好奇是否有另一种更清晰的方法来解决这个问题,也许使用正则表达式?

【问题讨论】:

  • 我投票结束这个问题,因为它是关于一般代码改进而不是特定问题。这可能被认为是“主要基于意见”,或者在另一个 Stack Exchange 站点上可能会更好,也许是代码审查。
  • 算法看起来不错,唯一的问题是它对每个不是括号的字符执行 6 次测试。也许您可以尝试从之前的字符串中提取所有括号,或者删除所有不是括号的内容。 (但不确定这是否会在所有情况下加速代码)。

标签: java regex string validation brackets


【解决方案1】:

您可以将字符串转换为char[] 并对其进行迭代。此外,您可以通过 Map 关闭左括号来使代码看起来更优雅:

// Initialize some helper structures:
private static Map<Character, Character> CLOSE_TO_OPEN;
private static Set<Character> OPENERS;
static {
    CLOSE_TO_OPEN = new HashMap<>();
    CLOSE_TO_OPEN.put(')', '(');
    CLOSE_TO_OPEN.put(']', '[');
    CLOSE_TO_OPEN.put('}', '{');
    OPENERS = new HashSet<>(closeToOpen.values());
}

public static boolean braces (String str) {
    Stack<Character> stack = new Stack<>();
    for (Character c : str.toCharArray()) {

        // If it's an opening bracket, push it to the stack
        if (OPENERS.contains(c)) {
            stack.push(c);
        } 
        // If it's a closing bracket, check the last opener
        else if (CLOSE_TO_OPEN.containsKey(c)) {
            try {
                Character opener = stack.pop();
                // Handle mismatches brackets
                if (!CLOSE_TO_OPEN.get(c).equals(opener)) {
                    return false;
                }
            } 
            // If the stack is empty, there's a redundant closer
            catch (EmptyStackException ignore) {
                return false;
            }
        }
    }

    // If the stack isn't empty once we're done with the string, 
    // there are redundant openers
    if (!stack.empty) {
        return false
    }
    return true;
} 

【讨论】:

    【解决方案2】:

    这是一个非常清晰的算法,看来你做对了。那么为了改变访问字符的方式,为什么不用String#charAt方法呢?

    您还可能希望将方法的返回类型从 String "YES""NO" 更改为 truefalse 类型的 boolean

    static boolean isValidBracketString(String string) {
        Stack<Character> stack = new Stack<>();
        for(int i=0; i< string.length(); i++){
            if(string.charAt(i) == '{' || string.charAt(i) == '[' || string.charAt(i) == '('){
                stack.push(string.charAt(i));
            } else if(string.charAt(i) == '}' || string.charAt(i) == '}' || string.charAt(i) == ')') {
                if(stack.size() == 0)
                    return false;
                switch(stack.pop()){
                    case '(':
                        if(string.charAt(i) != ')')
                            return false;
                        break;
                    case '[':
                        if(string.charAt(i) != ']')
                            return false;
                        break;
                    case '{':
                        if(string.charAt(i) != '}')
                            return false;
                        break;
                }
            }
        }
        return stack.size() == 0;
    }
    

    【讨论】:

    • 哦,太好了,这就是我要找的!谢谢!
    • 很高兴它有帮助。
    猜你喜欢
    • 1970-01-01
    • 2012-10-09
    • 2023-02-16
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    相关资源
    最近更新 更多