RPN使用链接列表

时间:2015-08-28 05:37:01

标签: c++

我无法搞清楚RPN计算器,我们必须使用链接列表进行此分配。 (我已使用stack<double>方法完成了作业,但它必须使用链接列表。

我在错误检查方面遇到了一些问题:

操作员太多(+ - / *) 操作数太多(双打) 除以零

程序应该继续采用和计算表达式,直到用户在一行上输入零(0)后跟一个新行。我也遇到了一些麻烦。因为我把我的错误检查“太多操作数”,所以 我不会允许我进行第二次计算,输出将是“太多的操作”

我似乎无法对“太多操作员”进行错误检查

我已经针对所需的错误检查尝试了几种不同的东西,并查看了不同站点上的许多其他RPN问题,因为您可以看到我尝试过并注释掉的一些内容。 任何帮助将不胜感激! 感谢

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;

struct NODE
{
       float num;
       NODE *next;
};

class stack
{
    private:
      NODE *head;

    public:
      stack();
      void push(float);
      float pop();
      int nElements();
      float display();
};

class RPN: public stack
{
    public:
      void add();
      void subtract();
      void multiply();
      void divide();
};


stack::stack()
{
     head = NULL;
}

void stack::push(float a_number)
{
     NODE *temp = new NODE;
     if (temp)
     {
        temp->num = a_number;
        temp->next = head;
        head = temp;
     }
}

float stack::pop()
{
    float number = 0;


    if (!head)
      {
         return 0;
      }
      else
      {
           NODE *temp = head;
           number = head->num;
           head = temp->next;
           delete temp;
      }
      return number;
}

int stack::nElements()
{
    int counter=0;
    for (NODE *node = head; node; node=node->next)
    {
        counter++;
    }
    return counter;
}

float stack::display()
{





   //ERROR CHECKING TOO MANY OPERANDS??? PRINTING TOO MANY OPERANDS           FOR :   100 10 50 25 / * - -2 / = , but still giving correct output && WILL NOT   ALLOW ME TO DO A SECOND CALCULATAION , OUTPUT WILL BE TOO MANY OPERANDS

       if(nElements() !=1)
      {
           cout << "Error: too many operands" << endl;
            return 1;
      }

       /*
        //   if( nElements() < 2 )
            {
                cout << "Error: too many operators" << endl;
                return 1;
            }
         */



               else //(nElements() > 0)
               {
                 float temp = pop();
                 cout << temp << endl;
                 push(temp);

                 return temp;

               }



}


void RPN::add()
{
     if (nElements()>=2)
     {
        push(pop() + pop());
     }
}

void RPN::subtract()
{
     if (nElements()>=2)
     {
        push(0 - pop() + pop());
     }
}

void RPN::multiply()
{
     if (nElements()>=2)
     {
        push(pop() * pop());
     }
}



 int RPN::divide()
{

    double op2;

    op2 = pop();

    if(op2 != 0.0)
    {
    push(pop() / op2);
    }
    else
    {
    cout << "Error: Division by zero.\n";     //??? Still printing output
    return -1;
    }
}


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

//Function prototype for perforOperation
int performOperation(const string& input, RPN& calculator);

Int main(){

    RPN calculator;
    string input;

     float num;

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


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

               // get input
               cin >> input;

               // check for being numeric value

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

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

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


               }
               }
   }

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;
}



int performOperation(const string& input, RPN& calculator)
{
    //double firstOperand = 0;
    //double secondOperand = 0;
    //double result;



    /*
    if( calculator.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( calculator.size() < 2 )
        {
            cout << "Error: too many operators" << endl;
            return 1;
        }
*/


    switch (input[0])
    {
    case '+': calculator.add();
              calculator.display();
              break;
    case '-': calculator.subtract();
              calculator.display();
              break;
    case '*': calculator.multiply();
              calculator.display();
              break;
    case '/':  calculator.divide();

                //if (firstOperand / 0) 
                //{
                //  cout << "Error: Divide by 0.\n";
                //}
               calculator.display();
              break;
    }
                            /*
                            if (secondOperand == 0)
                                        { // moved this test to here because it's the only place it matters.
                                            cout << "Error: Division by 0.\n";
                                            return -1;
                                        }
*/





return 0;

}

This is the sample input and output


Input   Output
10 15 + =   25
10 15 - =   -5
2.5 3.5 + = 6 (or 6.0)
10 0 / =    Error: Division by zero
10 20 * / = Error: Too many operators
12 20 30 / =    Error: Too many operands
-10 -30 - = 20
100 10 50 25 / * - -2 / =   -40




I got the error division by 0 check to work, It just keeps printing the output in addition to the error...How could I fix this?
int RPN::divide()
{

    double op2;

    op2 = pop();

    if(op2 != 0.0)
    {
    push(pop() / op2);
    }
    else
    {
    cout << "Error: Division by zero.\n";
    return -1;
    }
}

1 个答案:

答案 0 :(得分:0)

问题是你总是将计算结果留在堆栈上。因此,当您进行第二次计算时,您不会以空堆栈开始。简单的解决方法是在stack::display()

中删除此行
push(temp);

也可以将stack::display()重命名为stack::display_and_pop()