括号检查器完美地适用于单个测试用例,但对于所有测试用例,它给出了分段错误?

Parenthesis checker is working for individual test case perfectly but for all test case together it is giving segmentation fault?

本文关键字:测试用例 错误 分段 于所 检查 完美 单个 适用于      更新时间:2023-10-16

我已经使用 c++ 中的堆栈为括号检查器编写了代码,它单独适用于所有测试用例,但是当我一次性同时执行测试用例时,它会给出分段错误错误。

#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--) {
string str;
cin >> str;
stack<char> box;
int len = str.size();
box.push(str[0]);
for (int i = 1; i < len; i++) {
char temp = str[i];
char tp = box.top();
if (((tp == '{' && temp == '}') || (tp == '[' && temp == ']') || (tp == '(' && temp == ')')) && (!box.empty())) {
box.pop();
}
else {
box.push(temp);
}
}
if (box.empty() == true)
cout << "balanced" << endl;
else
cout << "not balanced" << endl;
}
return 0;
}

基本上你的方法非常好。这也是解析器用来匹配开始和结束标记的方法:堆栈。

应该做一些改进。您正在移动堆栈上的所有内容。您应该将牙套放在堆栈上。然后,您可以进行完全匹配。然后,您应该将牙套放在某个容器中,例如std::vectorstd::mapstd::string,就像我在以下示例中所做的那样。

对于您的赛格错误。当您尝试从空堆栈访问元素时,会发生这种情况。一种解决方案可能是利用C++所谓的布尔捷径评估。这意味着,一旦知道结果,布尔表达式的计算(例如,在 if 语句中)就会停止。

因此,如果您编写(!braceStack.empty() && (braceStack.top() == openingBraces[position]))并且堆栈为空,则不会调用 stack.top 函数。什么都不会发生。你会在保存的一边。

在现实世界中,你永远不会这样做,因为那样你会依赖副作用。您只需添加一个额外的 if。

在您的代码中,您在检查堆栈是否为空之前调用 top。这会导致未定义的行为 (UB)。

除了之前所做的改进之外,我还添加了注释、更好的变量名称、容器算法的使用等。

请看。

#include <iostream>
#include <string>
#include <stack>
// We define 2 strings with braces
// With that, searching is easier
const std::string openingBraces("([{<");
// Closing brace position must match to openeing brace position
const std::string closingBraces(")]}>");
int main()
{
// Get number of test rund from user
int numberOfTestRuns{ 0 };
std::cin >> numberOfTestRuns;
// Perform as many as tests, as user wants
while (numberOfTestRuns--) {
// Get string to analyze from user
std::string stringToAnalyze;
std::cin >> stringToAnalyze;
// Define a stack for braces
std::stack<char> braceStack{};
// Check all charcters in test string. From beginning to end
for (char currentCharToCheck : stringToAnalyze) {
// If there is an opening brace
if(openingBraces.find(currentCharToCheck) != std::string::npos) {
// Then put this on the stack. Do not push other element on the stack
braceStack.push(currentCharToCheck);
}
else {
// It was no opening brace
// Now we check, if it was a closing brace
if (size_t position = closingBraces.find(currentCharToCheck); position != std::string::npos) {
// CLosing brace found. First check, if there are elements on the stack
// And then check, if we have a fmatching brace on the stack top
if (!braceStack.empty() && (braceStack.top() == openingBraces[position])) {
// In this case we remove the stacke top. ELse not. Will lead to no match
braceStack.pop();
}
}
// Else Nothing: It was any other character, no brace
}
}
// If the stack is empty, then we could find a match for everything
if (braceStack.empty() == true)
std::cout << "balanced" << 'n';
else
std::cout << "not balanced" << 'n';
}
return 0;
}