问题在于平衡括号。我正在使用堆栈进行操作。它不适用于仅一个测试用例,即')'。否则它工作正常

Posted

技术标签:

【中文标题】问题在于平衡括号。我正在使用堆栈进行操作。它不适用于仅一个测试用例,即\')\'。否则它工作正常【英文标题】:The question is on balancing parentheses. I'm doing it using stack. It doesn't works on only one test case i.e ')'. Else it is working fine问题在于平衡括号。我正在使用堆栈进行操作。它不适用于仅一个测试用例,即')'。否则它工作正常 【发布时间】:2021-12-15 00:45:12 【问题描述】:
    bool areBracketsBalanced(char exp[]) 
  int len = strlen(exp);
  stack<char> s;
  for(int i=0;i<len;i++)
    char ch = exp[i];
    if(ch=='(' || ch=='[' || ch=='')
      s.push(ch);
    
    else if(!s.empty() && ch==')')
      if(s.top()=='(')
        s.pop();
      
      else if(s.top()!='(')
        continue;
      
    
    else if(!s.empty() && ch==']')
      if(s.top()=='[')
        s.pop();
      
      else if(s.top()!='[')
        continue;
      
    
    else if(!s.empty() && ch=='')
      if(s.top()=='')
        s.pop();
      
      else if(s.top()!='')
        continue;
      
    
    
    else
      continue;
    
  
  if(s.empty())
    return 1;
  
  else
    return 0;
  
 

问题在于平衡括号。我正在使用堆栈进行操作。它不适用于仅一个测试用例,即')'。否则它工作正常。请向我建议一个适用于测试用例的更改,因为我无法弄清楚。

【问题讨论】:

“不起作用”不是一个好的问题描述。请描述确切的输入、预期行为和实际行为。代码也不完整。请以minimal reproducible example 的形式提供完整代码。最后,请注意 C 和 C++ 是不同的语言 - 我已经删除了 C 标记,因为它看起来是 C++ 代码。 您只需忽略不匹配的括号或没有左括号的右括号。此外,为什么使用10 而不是true/ false。此外,所有这些continue; 语句都是不必要的;如果当前循环迭代的执行路径上没有语句,则不必明确提及要继续下一个循环迭代。 【参考方案1】:

因此,右括号基本上存在设计问题。如果右括号多于左括号,则您的方法将不起作用。

原因是你基本检测到了问题,但没有说明。

共有三个continue 语句。这些应该修改,因为在else 部分中,很明显我们存在不平衡。

但是除了这个问题之外,还有很多其他的问题需要改进。

我在你的原始代码中添加了 cmets。

// All variables should always be initialized
#include <stack>     
#include <cstring>     // You should basically not use C-Style headers and functions

using namespace std;   // You should never open the full std namespace. Please use always fully qualified names in it


bool areBracketsBalanced(char exp[])   // You should not use C-Style strings something decaying to pointers
    int len = strlen(exp);        // You shold not use C-Style strings and functions. This can be made const
    stack<char> s;
    for (int i = 0; i < len; i++)     // With C++Strings, you may use the range based for loop
        char ch = exp[i];   // Meaninful variable names should be used. ch can be made const.

        // You do not consider the case when you get a closing bracket and the stack is empty or the wrong element is on the stack
        if (ch == '(' || ch == '[' || ch == '') 
            s.push(ch);
        
        else if (!s.empty() && ch == ')') 
            if (s.top() == '(') 
                s.pop();
            
            else if (s.top() != '(') 
                continue;            // You should not use continue in this case. Continue is nearly like a goto. 
                                    // And it is often an indicator for a bad design on SWE.2 level
            

        
        else if (!s.empty() && ch == ']')   // Somehow repeating. May be redesigned and refactored.
            if (s.top() == '[') 
                s.pop();
            
            else if (s.top() != '[') 
                continue;    // See above
            
        
        else if (!s.empty() && ch == '') 
            if (s.top() == '') 
                s.pop();
            
            else if (s.top() != '') 
                continue;     // See above
            
        

        else 
            continue;  // And again.
        
    
    if (s.empty()) 
        return 1;    // A function should always have onle one entry and exit point. So, please no multiple returns.
    
    else 
        return 0;    // C++ has the constants true and false, which should be used for the return value.
    


int main() 
    char test[] = "[]";
    return areBracketsBalanced(test);


那么,让我们开始重构你的代码吧。

我们将添加 cmets 和有意义的名称并解决问题。但还是不好。

#include <iostream>
#include <stack>     
#include <cstring>     

using namespace std;   


bool bracketsAreBalanced(char *stringToCheck)  

    // We want to itearte over all characters in the C-String
    // We expect a 0-terminated C-String here
    const size_t lengthOfStringToCheck strlen(stringToCheck) ;

    // We use a stack for the openining brackets to have a change to do the balancing
    stack<char> bracketStack;

    // We will use an indicator, if the result is so far OK
    // We initially assume that the result is OK and the brackets are balanced
    bool balanceIsOK true ;

    // Now, iterate over all characters in the input string.
    // Additionally, if we found an imbalance then we terminate the loop immediately
    for (size_t i = 0; i < lengthOfStringToCheck && balanceIsOK; i++) 

        const char ch = stringToCheck[i];   

        // If there is a closing bracket and not opening bracket on the stack, the something is wrong
        // In this case we have more closing then opening brackets
        if ((ch == ')' || ch == ']' || ch == '') && bracketStack.empty()) 
            balanceIsOK = false;
        
        // Check for an opening bracket and push it on the stack
        else if (ch == '(' || ch == '[' || ch == '') 
            bracketStack.push(ch);
        
        // We are here, becuase we did not see an opening bracket.
        // Now check all closing bracket types, and if their corresponding opening part is there
        else if (!bracketStack.empty() && ch == ')') 
            if (bracketStack.top() == '(') 
                bracketStack.pop();
            
            else if (bracketStack.top() != '(') 
                balanceIsOK = false;;
                                    
        
        else if (!bracketStack.empty() && ch == ']') 
            if (bracketStack.top() == '[') 
                bracketStack.pop();
            
            else if (bracketStack.top() != '[') 
                balanceIsOK = false;;
            
        
        else if (!bracketStack.empty() && ch == '') 
            if (bracketStack.top() == '') 
                bracketStack.pop();
            
            else if (bracketStack.top() != '') 
                balanceIsOK = false;;
            
        
    
    // If there are still brackets pn the stack, then we have an imbalance
    if (!bracketStack.empty())
        balanceIsOK = false;

    return balanceIsOK;    


int main() 
    char test[] = "aa[aaaaaaaaaa]aa";

    if (bracketsAreBalanced(test)) 
        cout << "Balanced\n";
    
    else 
        cout << "Not Balanced\n";
    
    return 0;



在 c++ 中,我们可以利用更多可用且随时可用的功能。

我们需要以某种方式对匹配对进行建模。我们可以通过许多可能的解决方案来做到这一点,例如std::unordred_map

然后我们可以对其进行迭代并与对部分进行比较。

查看一个可能的示例:

#include <iostream>
#include <unordered_map>
#include <stack>
#include <string>

using Pairs = std::unordered_map<char, char>;
using BracketsSeen = std::stack<char>;

const Pairs pairs '(',')','[',']','','' ;


bool bracketsAreBalanced(std::string& stringToCheck) 

    // Here we store all bopening brackets that we saw before
    BracketsSeen bracketsSeen;

    // Resulting function value. We first assume that everthing is OK
    bool balanceIsOK true ;

    // Go through all characters in the string
    for (const char c : stringToCheck) 

        // And now check for each existing pair of brackets
        for (const auto& [openingBracket, closingBracket] : pairs) 

            // Push all opening bracktes onto the stack
            if (c == openingBracket)
                bracketsSeen.push(c);

            // If we have a closing bracket, then check, if we have the matching opening bracket
            else if (c == closingBracket) 
                if (bracketsSeen.empty() or bracketsSeen.top() != openingBracket) 
                    balanceIsOK = false;   break;
                
                else
                    bracketsSeen.pop(); // Match found. Remove from the stack
            
        
        // Unfortunately in C++17 there is no other way. So stop, if result is known.
        if (not balanceIsOK) break;
    
    return balanceIsOK;

int main() 
    std::string test "aa[aaaaaaaaaa]aa" ;

    if (bracketsAreBalanced(test)) 
        std::cout << "Balanced\n";
    
    else 
        std::cout << "Not Balanced\n";
    
    return 0;



请看

【讨论】:

以上是关于问题在于平衡括号。我正在使用堆栈进行操作。它不适用于仅一个测试用例,即')'。否则它工作正常的主要内容,如果未能解决你的问题,请参考以下文章

Java 平衡表达式检查 [()]

如何确定表达式是不是在堆栈中具有平衡括号? [复制]

基本递归,检查平衡括号

平衡的括号[UVA-673]

堆栈平衡

使用 RegEx 平衡匹配括号