平衡括号 - 当堆栈是强制性的?

时间:2016-01-03 14:10:58

标签: c algorithm

如果我想检查一个字符串是否有用括号,我可以使用这个简单的代码:

int counter = 0;
for(int i = 0; i < length_of_string; i++){
    if(string[i] == '(' )
       counter++;
    else if(string[i] == ')' )    // string is a char array
       counter--;
    if(counter < 0)
       return -1; // error because the ')' should come AFTER '('
}
if(counter == 0)
     return 0; // the string is OK
else
     return -1; // unbalanced

我的问题是 - 我认为这段代码做得很好,但我已经看到一些使用堆栈的实现。这是为什么?使用堆栈是否能够处理更详细的案例?

4 个答案:

答案 0 :(得分:6)

如果只是平衡括号,使用堆栈具有以下优点:

  • 您可以将用户指向未闭合括号的偏移量;
  • 您可以平衡不同类型的分组运算符,例如[]{}(),并验证它们是否已正确嵌套。

请注意,如果要支持字符串,字符,正则表达式文字以及可能的注释,则可能需要更仔细地解析字符串。

答案 1 :(得分:5)

如果您只想检查不匹配的括号,则无需创建堆栈,您的代码就可以了。如果要解析表达式(数学例如),您肯定需要一堆字符来推送运算符和括号。阅读this for more information

答案 2 :(得分:2)

使用stack非常容易理解且效率很高。这是因为当您看到开始标记(Push)和(时,当您看到结束标记(Pop)时,您只能)到堆栈。这与使用计数器的代码非常相似。

要检查带括号的字符串是否合法,您只需return is_stack_empty(my_stack);(或其任何变体)即可获得结果。

注意:正如人们所说的那样,在这里使用stack可能不是可行的方法,因为计数器可以完美地完成工作。但如上所述,stack可以很好地处理数学表达式,例如可以有多种类型标记的表达式(() , [] , {})。

答案 3 :(得分:0)

以下是使用 Stack 的Java代码,它可以帮助您平衡多个括号

public boolean isValid(String s) {
    HashMap<Character, Character> closeBracketMap = new HashMap<Character, Character>();
    closeBracketMap.put(')', '(');
    closeBracketMap.put(']', '[');
    closeBracketMap.put('}', '{');
    HashSet<Character> openBracketSet = new HashSet<Character>(
        closeBracketMap.values());
    Stack<Character> stack = new Stack<Character>();

    char[] chars = s.toCharArray();
    for (int i = 0; i < chars.length; i++) {
        char cur = chars[i];
        if (openBracketSet.contains(cur)) {
            stack.push(cur);
        } else { // close brackets
            if (stack.isEmpty()) {
                return false;
            }
            if (closeBracketMap.get(cur) != stack.peek()) {
                return false;
            }
            stack.pop();
        }
    }

    return stack.isEmpty();
}

以下是不使用 Stack

的代码
public class Groups{
  public static boolean groupCheck(String s) {
    int len;
    do {
      len = s.length();
      s = s.replace("()", "");
      s = s.replace("{}", "");
      s = s.replace("[]", "");
    } while (len != s.length());
    return s.length() == 0;
  }
}

这意味着我们将逐个删除。

例如:String s =&#34;&#34; (len = 10; s.length()= 10)它将删除&#34; []&#34;,&#34; []&#34;,&#34;()&#34;。

然后s =&#34;({})&#34; (s.length()= 4)它将继续删除&#34; {}&#34;。

然后s =&#34;()&#34; (s.length()= 2),它将继续删除&#34;()&#34;。

然后s =&#34;&#34; (s.length()= 0)。它会打破循环因为((len == 10)!=(s.length()== 0))。

然后我们将能够检查它是否属实。 :)