问题在于平衡括号。我正在使用堆栈进行操作。它不适用于仅一个测试用例,即')'。否则它工作正常
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++ 代码。 您只需忽略不匹配的括号或没有左括号的右括号。此外,为什么使用1
和0
而不是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;
请看
【讨论】:
以上是关于问题在于平衡括号。我正在使用堆栈进行操作。它不适用于仅一个测试用例,即')'。否则它工作正常的主要内容,如果未能解决你的问题,请参考以下文章