用C ++反转波兰表示法计算器

时间:2017-05-16 16:07:24

标签: c++ algorithm rpn

我正在尝试使用字符串作为参数在C ++中编写RPN算法。 我正在使用堆栈和字符串进行读取 我知道算法是如何工作的,但我得不到正确的结果,我总是得到0.这是我的代码:

#include <iostream>
#include <stack>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

float RPN(string s) {
    stack<int> p;
    int n1, n2;

    string values[s.size()];
    for (unsigned int i = 0; i < s.size(); i++)
        values[i] = s.at(i);

    for (unsigned int i = 0; i < s.size(); i++) {
        if (s.at(i) != '+' || s.at(i) != '-' || s.at(i) != '*'
                || s.at(i) != '/') {
            int n;
            istringstream(values[i]) >> n;
            p.push(n);
        }

        else {
            n1 = p.top();
            p.pop();
            n2 = p.top();
            p.pop();
            switch (s.at(i)) {
            case '+':
                p.push(n1 + n2);
                break;
            case '-':
                p.push(n2 - n1);
                break;
            case '*':
                p.push(n1 * n2);
                break;
            case '/':
                p.push(n2 / n1);
                break;
            }
        }
    }

    if (p.size()) {
        int resul = p.top();
        while (p.size())
            p.pop();
        return resul;
    }
    return 0;
}

这是调用方法:

void callRPN() {

    string s1 = "56-";
    string s2 = "65-";
    string s3 = "843+2*-";
    string s4 = "62+83-*4/";

    cout << s1 << " valor: " << RPN(s1) << endl;
    cout << s2 << " valor: " << RPN(s2) << endl;
    cout << s3 << " valor: " << RPN(s3) << endl;
    cout << s4 << " valor: " << RPN(s4) << endl;
}

控制台结果:

56- valor: 0
65- valor: 0
843+2*- valor: 0
62+83-*4/ valor: 0

我的代码中有什么错误?如果有人可以帮助我,我会很感激。谢谢。

1 个答案:

答案 0 :(得分:0)

至少有一个主要问题是输入无效(它们不是正确的反向波兰表示法),并且您不会检查无效输入。

关于算法的几点:

int resul = p.top();
// At this point, p.size() should be 1 - it should only contain the answer.
// If it's anything other than 1, the expression you were passed is wrong
// and you should throw an exception.
while (p.size())
    p.pop();

此外,您应该检查以确保在执行此操作时堆栈中有足够的项目:

n1 = p.top();
p.pop();
n2 = p.top();
p.pop();

如果不足,则应抛出异常,因为这意味着输入无效。

至少部分反向波兰表示法输入不正确,具体取决于它们的解释方式。例如,56-应该被解释为5 - 6还是56 -?如果是后者,则以下内容不正确:

62+83-*4/

由于与上述相同的原因,这实际上应该抛出异常。尝试追踪这个;当你执行62 +时,例如62加什么?在反向波兰表示法中执行62 + 83的正确方法是62 83 +。此时,堆栈应包含145 145(意味着它在-*处无效这点)。如果您尝试(62 + 83) / 4,则正确的编码为:

62 83 + 4 /

由于我上面提到的相同原因,我不清楚-*部分应该做什么。

所以,实际上,这应该验证输入。

也许更重要的是,以下内容不正确:

if (s.at(i) != '+' || s.at(i) != '-' || s.at(i) != '*'
            || s.at(i) != '/') {
        int n;
        istringstream(values[i]) >> n;
        p.push(n);
    }

您应该在此||替换&&;如果不是任何运算符,你想要推入堆栈。在这种情况下,如果它不是+运算符,它只会推到堆栈上(意味着它会尝试将其推入堆栈,如果它是,例如,-运算符。