否则,如果语句无法正常运行

时间:2019-08-30 23:51:19

标签: c++ if-statement stack

当我遇到这种情况时,我正在使用堆栈实现来解决平衡括号问题,在这种情况下,我正在使用'else-if'语句检查右括号,但是输出与预期的不同。将所有的“ else-if”语句更改为普通的“ if”语句后,代码可以正常工作。 我想知道为什么会这样,因为我一直认为使用'else-if'语句是更好的做法。

int main(){
    stack<char> bracks;
    string s;   // input string: {a+(b+c-[e-f])*d}
    cin >> s;
    for(int i = 0; i < s.size(); i++){
        if(s[i] == '{' || s[i] == '(' || s[i] == '[')    bracks.push(s[i]);
        else if(s[i] == '}')
            if(bracks.top() == '{')    bracks.pop();
        else if(s[i] == ')')
            if(bracks.top() == '(')    bracks.pop();
        else if(s[i] == ']')
            if(bracks.top() == '[')    bracks.pop();
    }
    if(bracks.empty())  cout << "Balanced\n";
    else    cout << "Unbalanced\n";
}

输入字符串“ {a +(b + c- [e-f])* d}”的预期输出为“平衡”,但输出为“不平衡”。

3 个答案:

答案 0 :(得分:4)

  

使用'else-if'语句是一种更好的做法。

ifelse-if是不同的事物,它们在不同的情况下使用。不论好坏都没有。

考虑该代码:

if (c1) if (c2) a else b

编译器看到它的方式是:

if (c1) {
    if (c2)
        a
    else
        b
}

原因是else始终属于最里面的if。 在您的情况下,您的情况意味着:

if(s[i] == '{' || s[i] == '(' || s[i] == '[') {
    bracks.push(s[i]);
} else if(s[i] == '}') {
    if(bracks.top() == '{') {
        bracks.pop();
    } else if(s[i] == ')') {
        if(bracks.top() == '(') {
            bracks.pop();
        } else if(s[i] == ']') {
            if(bracks.top() == '[') {
                bracks.pop();
            }
        }
    }
}

您的缩进显示这不是您想要的。

答案 1 :(得分:2)

您需要一些其他的花括号,以便else适用于正确的if

for(int i = 0; i < s.size(); i++){
    if(s[i] == '{' || s[i] == '(' || s[i] == '[')    bracks.push(s[i]);
    else if(s[i] == '}')
    {
        if(bracks.top() == '{')    bracks.pop();
    }
    else if(s[i] == ')')
    {
        if(bracks.top() == '(')    bracks.pop();
    }
    else if(s[i] == ']')
    {
        if(bracks.top() == '[')    bracks.pop();
    }
}

Live demo

正确缩进代码将对此有所帮助。

答案 2 :(得分:1)

您的问题是您的for循环中的代码,我在这里逐字引用

    if(s[i] == '{' || s[i] == '(' || s[i] == '[')    bracks.push(s[i]);
    else if(s[i] == '}')
        if(bracks.top() == '{')    bracks.pop();
    else if(s[i] == ')')
        if(bracks.top() == '(')    bracks.pop();
    else if(s[i] == ']')
        if(bracks.top() == '[')    bracks.pop();

的缩进暗示(对于人类读者)特定的顺序。但是,编译器将忽略缩进。如果我们使用缩进(以及几个额外的换行符)使代码在编译器中看起来像我们一样,我们将得到

    if(s[i] == '{' || s[i] == '(' || s[i] == '[')
        bracks.push(s[i]);
    else if(s[i] == '}')
        if(bracks.top() == '{')
            bracks.pop();
        else if(s[i] == ')')
            if(bracks.top() == '(')
                bracks.pop();
            else if(s[i] == ']')
                if(bracks.top() == '[')
                    bracks.pop();

因此,我们实际上有三个嵌套级别,其中您的缩进仅暗示一个。事实是,由于编译器(大多数情况下)会忽略空格,因此就编译器而言,这两个代码示例是相同的。

由于人类会解释空白,而编译器会忽略它,因此通常被认为是良好实践的准则还涉及添加{}以确保以合理的方式对代码进行逻辑分组(希望)是指人类和编译器将解释代码具有相同的含义。例如,以下代码在每个嵌套的if语句的开始和结尾处添加一对{}

    if(s[i] == '{' || s[i] == '(' || s[i] == '[')
    {
        bracks.push(s[i]);
    }
    else if(s[i] == '}')
    {
        if(bracks.top() == '{')
        {
            bracks.pop();
        }
        else if(s[i] == ')')
        {
            if(bracks.top() == '(')
            {
                bracks.pop();
            }
            else if(s[i] == ']')
            {
                if(bracks.top() == '[')
                {
                    bracks.pop();
                }
            }
        }
    }

此示例代码与您的示例代码具有相同的含义,但(主观上)一个人可以更轻松地知道将哪些代码段组合在一起。

问题是,有许多用于缩进代码和放置花括号的方案。您会发现倡导者在某些方面有所不同。例如,以下内容是相同的,不同之处在于它遵循以下规则:开头{应该与与其关联的if语句在同一行。

    if(s[i] == '{' || s[i] == '(' || s[i] == '[') {
        bracks.push(s[i]);
    }
    else if(s[i] == '}') {
        if(bracks.top() == '{') {
            bracks.pop();
        }
        else if(s[i] == ')') {
            if(bracks.top() == '(') {
                bracks.pop();
            }
            else if(s[i] == ']') {
                if(bracks.top() == '[') {
                    bracks.pop();
                }
            }
        }
    }

同样,客观地讲,这段代码具有相同的含义(就编译器而言)。但是,有些人会倡导一种,有些人会倡导另一种。