检查平衡分组字符时在线判断运行时错误

时间:2015-12-18 15:27:04

标签: c++ stack runtime-error

这是我的代码,用于检查一组分组字符是否正确平衡。 它在我的本地机器上工作正常,但在线判断给我一个运行时错误。

#include <iostream>
#include <string>
#include <stack>
using namespace std;

bool balanced(string exp)
{
    stack<char> st;
    int i;
    for(i=0;i<exp.length();i++)
    {
            if(exp[i]== '{' || exp[i]=='[' || exp[i]== '(') st.push(exp[i]);
            else if(exp[i]=='}'){
                if(st.top() == '{' && !st.empty()) st.pop();
                else return false;
            }
            else if(exp[i]==')'){
                if(st.top() == '(' && !st.empty()) st.pop();
                else return false;
            }
            else if(exp[i]==']'){
                if(st.top()=='['  && !st.empty()) st.pop();
                else return false;
            }
    }
    if(st.empty())return true;
    else return false;
}

int main() {
    string exp;int n;
    cin >> n;
    cin.ignore();
    while(n--)
    {
        getline(cin,exp);
        bool balance = balanced(exp);
        if(balance == true)cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}

2 个答案:

答案 0 :(得分:5)

if(st.top() == '{' && !st.empty())

你应该在登顶前检查堆栈空虚。

if(!st.empty() && st.top() == '{')

答案 1 :(得分:2)

<强>间距

我的间距和支具使用方面存在一些问题。首先,你的循环中的逻辑是WAY太缩进了。单个缩进很好。其次,不要在与if相同的行上写入逻辑,除非它是一个微不足道的条件并且没有else - 并且永远不会在与else相同的行上写入逻辑。这是不可能阅读的。非常喜欢整个写作括号。还要在if

之后添加一个空格

这是平衡的,用更好的间距重写:

bool balanced(string exp)
{
    stack<char> st;
    for(int i=0; i<exp.length(); i++)
    {
        if (exp[i]== '{' || exp[i]=='[' || exp[i]== '(') {
            st.push(exp[i]);
        }
        else if (exp[i]=='}') {
            if (st.top() == '{' && !st.empty()) {
                st.pop();
            }
            else {
                return false;
            }
        else if (exp[i]==')') {
            if(st.top() == '(' && !st.empty()) {
                st.pop();
            }
            else {
                return false;
            }
        }
        else if(exp[i]==']') {
            if(st.top()=='['  && !st.empty()) {
                st.pop();
            }
            else {
                return false;
            }
        }
    }

    if (st.empty()) {
        return true;
    }
    else {
        return false;
    }
}

现在我可以阅读您的代码,我们可以解决逻辑问题。

处理bool

if (expr) return true; else return false;结尾。这完全等同于:

return st.empty();

同样,你有:

bool balanced = balanced(exp);
if (balance == true) ...
else ...

永远不要写== true,你甚至不需要这里的变量:

if (balanced(exp)) {
    ...
}
else {
    ...
}

甚至可以是三元:

cout << (balanced(exp) ? "Yes" : "No") << endl;

<强>重复

你的逻辑非常重复。我们有三种类型的开放和三种类型的封闭 - 我们以相同的方式处理开放,我们以相同的方式处理关闭 - 检查堆栈是否为非空且顶部元素是等效的开放。对于除了那些6之外的任何其他字符 - 我们不在乎。

因此,我们可以将我们的逻辑折叠为更明确地等同于三个关闭。此外,交换机也有很多帮助:

switch (exp[i]) {
case '{':
case '[':
case '(':
    st.push(exp[i]);
    break;
case '}':
case ']':
case ')':
    if (!st.empty() && st.top() == open_brace(exp[i])) {
        st.pop();
    }
    else {
        return false;
    }
    break;
default:
    break;
}

您必须实施open_brace才能做正确的事情。这样可以节省大量代码,从而减少错误。另请注意条件的重新排序 - 您需要先检查非空虚。

<强>参数

balanced不会修改它的参数,或者除了迭代它之外真的需要对它做任何事情。所以请参考const:

bool balanced(std::string const& expression)

最后......

<强> using namespace std;

Avoid it.