用于C ++的RPN计算器

时间:2015-08-24 20:38:13

标签: c++

我正在尝试为RPN计算器编写代码,我正在努力使其正确计算多于一个"左"和"对"操作数。

到目前为止,我的代码适用于以下输入: 10 15 + = 25

我无法弄清楚如何正确输出这些输入:

输入:100 10 50 25 / * - -2 / =输出:-40

此外,现在我只是将堆栈大小除以2,这适用于某些错误检查,但是它会输出类似于上/下输入的错误。 100 10 50 25 / * - -2 / = -40

如何获取以下这两个输入的错误检查代码?

输入:10 20 * / =输出:错误:操作员太多

    12 20 30 / =                   Error: Too many operand

非常感谢任何帮助,谢谢!

#include <iostream>
#include <stack>
#include <string>
#include <sstream> //make use of a class called istringstream
#include<iomanip>

using namespace std;

//Function prototype for isOperator
bool isOperator(const string& input);

//Function prototype for perforOperation
int performOperation(const string& input, stack<double>& calcStack);

int main()
{

    cout << "RPN Calculator: " << endl;
    cout << "Input\n";

    stack<double> calcStack;
    string input;


        while(input != "0")
        {
            //Terminate program when 0 is entered by user
            while(input != "=")
            {

            // get input
            cin >> input;

            // check for being numeric value
            double num;

                if(istringstream(input) >> num)
                {
                    //use push function
                    calcStack.push(num);
                }

                // check for operator
                else if(isOperator(input))
                {
                    performOperation(input, calcStack);
                }

                // If user enters 0 on a line followed by a new line, the program exits     ????????????
                else if(input == "0\n")
                {
                    return -1;
                }

                // invalid output check
                //else
                //{
                    //cout << "Invalid input" << endl;
                //}
            }
            }
}

    bool isOperator(const string& input)
    {
        string operators[] = {"-", "+", "*", "/"};

        for(int i=0; i<4; i++)
        {
            if(input == operators[i])
            {
                return true;
            }
        }

        return false;
}


int performOperation(const string& input, stack<double>& calcStack)
{
    double firstOperand;
    double secondOperand;
    double result;

    if( calcStack.size() > 2 )                      //Error check gives a false error for last input ???
    {
        cout << "Error: too many operands" << endl;
        return 1;
    }

    //Error chceck for too many operators           ////STILL PRINT OUTPUT???
    if( calcStack.size() < 2 )
        {
            cout << "Error: too many operators" << endl;
            return 1;
        }


    secondOperand = calcStack.top();
    calcStack.pop();


    firstOperand = calcStack.top();
    calcStack.pop();


    if(input == "-")
    {
        result = firstOperand-secondOperand;
    }

    else if (input == "+")
    {
        result = firstOperand + secondOperand;
    }

    else if (input == "*")
    {
        result = firstOperand * secondOperand;
    }

    else if( input == "/")
    {
    result = firstOperand / secondOperand;
    }


    // If user enters 0 on a line followed by a new line, the program exits         ???????????
    else if(input == "0\n")
    {
    return -1;
    }

        //Division by zero error
        if(secondOperand == 0)
            {
                cout << "Error: Division by 0.\n";
                return -1;
            }

    cout << "Output\n";
    cout << result << endl;
    calcStack.push(result);

return 0;

}

2 个答案:

答案 0 :(得分:0)

这里的代码

if( calcStack.size() > 2 )                      
{
    cout << "Error: too many operands" << endl;
    return 1;
}

需要转移到主要并稍微转换

else if(isOperator(input))
{
    performOperation(input, calcStack);
}
else if(input == "=")
{
    if (calcStack.size() != 1)
    {
        cout << "Error: too many operands" << endl;
        return 1;
    }
    else
    {
        cout << "Result: " << calcStack.top();
        // now decide whether or not you are preserving the result for
        // the next computation
        calcStack.pop(); // Assuming not keeping result
    }
}

这意味着您需要重新考虑此循环while(input != "=")

你真的很亲密。

两个建议:

您可以优化isOperator功能。

bool isOperator(const string& input)
{
    static const string operators ="-+*/";
    if (input.length() == 1) // right size to be an operator.
    {
        return operators.find_first_of(input[0]) != string::npos;
        // look in the operator string for the first (and only) character in input
    }
    return false;
}

由于您知道运算符中只有一个字符,因此您可以使用比if / else更优雅的字符:

switch (input[0])
{
    case '-':
        result = firstOperand - secondOperand;
        break;
    case '+':
        result = firstOperand + secondOperand;
        break;
    case '*':
        result = firstOperand * secondOperand;
        break;
    case '/':
        if (secondOperand == 0)
        { // moved this test to here because it's the only place it matters.
            cout << "Error: Division by 0.\n";
            return -1;
        }
        result = firstOperand / secondOperand;
        break;
}

处理评论的附录

到目前为止,您的代码应该已经发生了很大变化,您可能希望使用当前代码开始一个新问题。如果没有,这就是我在评论中所说的。

else if(isOperator(input))
{
    if (performOperation(input, calcStack) != 0)
    {
        // empty out the stack and delete all pending user input.
        calcStack.clear(); 
        cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
        cout << "Bad input. Try again." << endl;
        break; // exit input loop.
     }
}
else if(input == "=")
{
...

答案 1 :(得分:0)

double helpRpnFunc(string arr[], int& size) {
    if (size == 0)
        throw "Error: Too many operators\n";
    try {
        return stoi(arr[size - 1]);
    }
    catch (invalid_argument) {
        char operator1 = arr[size - 1][0];
        double secondOperand = helpRpnFunc(arr, --size), firstOperand = helpRpnFunc(arr, --size);
        switch (operator1) {
        case '+':
            return firstOperand + secondOperand;
        case '-':
            return firstOperand - secondOperand;
        case '*':
            return firstOperand * secondOperand;
        case '/':`enter code here`
            if (secondOperand == 0)
                throw "Error: canot divide by 0!\n";
            return firstOperand / secondOperand;
        }
    }
}
string rpnFunc(string arr[], int size) {
    try {
        string str = to_string(helpRpnFunc(arr, size));
        if (size > 1)
            throw "Error: too many operands";
        return str.substr(0, str.find(".") + 3);
    }
    catch (const char* error) {
        return error;
    }
}
int main()
{
    string arr1[] = { "100","10","50","25","/","*","-","-2","/" };
    int size = 9;
    cout << rpnFunc(arr1, size) << endl;
    string arr2[] = { "10","20","*","/" };
    size = 4;
    cout << rpnFunc(arr2, size) << endl;
    string arr3[] = { "12","20","30","/" };
    cout << rpnFunc(arr3, size) << endl;
}