0

所以,我有以下(kludgy!)代码用于后缀表达式转换器和计算器的中缀(正如我在上一篇文章中提到的:简单的数值表达式求解器,感谢大家!):

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

using namespace std;

int main()
{
    stack<char> operators;  
    stack<char> output;
    stack<char> temp;       
    stack<char> answer; 

    string command;

    cout << "=>";
    cin >> command;

    // "Shunting Yard" algorithm
    // source: http://en.wikipedia.org/wiki/Shunting-yard_algorithm
    for(int i=0; i<command.size(); i++)
    {
        switch(command[i])
        {
        case '*': case '+': case '-': case '/': case'(': 
            operators.push(command[i]);
            break;

        case ')':
            while(operators.top() != '(')
            {
                output.push(operators.top());
                operators.pop();
            }
            operators.pop();
            break;

        default:
            output.push(command[i]);
            break;
        }
    }

    while(!operators.empty())
    {
        output.push(operators.top());
        operators.pop();
    }

    while(!output.empty())
    {
        temp.push(output.top());
        output.pop();
    }

    while(!temp.empty())
    {
        if(temp.top() == '+')
        {
            int a = atoi(&answer.top());
            cout << "A=" << a << endl;
            answer.pop();
            int b = atoi(&answer.top());
            cout << "B=" << b << endl;
            answer.pop();
            answer.push(b+a);
        } else {
            answer.push(temp.top());
        }
        temp.pop();
    }

    cout << answer.top() << endl;

    system("pause");
    return 0;
}    

无论如何,问题是:如果我输入,例如,3+4,结果是“&”,而正确的结果是“7”。那么,我的代码有什么问题?

4

2 回答 2

0

替换这部分代码:

if(temp.top() == '+')
    {
        int a = atoi(&answer.top());
        cout << "A=" << a << endl;
        answer.pop();
        int b = atoi(&answer.top());
        cout << "B=" << b << endl;
        answer.pop();
        answer.push(b+a);
    } 

和:

 if(temp.top() == '+')
    {
        int a = answer.top() - '0';
        cout << "A=" << a << endl;
        answer.pop();
        int b = answer.top() - '0';
        cout << "B=" << b << endl;
        answer.pop();
        answer.push(b+a);
    } 

将解决您的问题。

于 2012-06-26T03:36:02.577 回答
0

这里有两个问题。

第一的:

int a = atoi(&answer.top());

atoi 采用指向以空字符结尾的字符串的指针。但是 &answer.top() 只是一个指向单个字符的指针。所以 atoi 将从那个字符开始读取,然后继续遍历内存,直到找到一个 '\0' 字符(或非数字)。根据您的平台上堆栈的实现方式,这可能意味着它读取“4”,然后是“3”,然后是“\0”,所以它以“43”结尾。或者它可能会读取“4”,然后是一些恰好以“8675309j”开头的未初始化内存,所以它以“48675309”结尾。

如果你想知道为什么编译器没有警告你这个错误,问题是 C 风格的字符串和指向单个字符的指针在语法上是完全相同的类型 (char*),所以编译器不能告诉你'除非它理解 atoi 的语义,否则将它们混合在一起。这是最好使用 C++ 字符串类和函数而不是基于 C char* 的函数的众多原因之一。

第二:

answer.push(b+a);

b+a 是一个 int,但您将它推入一堆字符中。因此,即使它具有正确的值,您也会推送字符“\007”,而不是字符“7”。您需要对其进行重新字符串化。但是在这种情况下,您显然得到了类似 305419814 的内容,当转换为 char 时,它会被截断为低 8 位 (38),而 38 是“&”。

于 2012-06-26T04:38:19.113 回答