【问题标题】:RPN using Linked Lists使用链表的 RPN
【发布时间】:2015-08-28 05:37:01
【问题描述】:

我在计算一个 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;
    }
}

【问题讨论】:

  • 我不确定它是否能解决问题,但请尝试将RPN calculator; 移动到循环内。我认为上一次迭代的结果是绊倒它。 (另外,&gt;&gt; 会跳过空格,因此您永远不会阅读 "0\n"。)

标签: c++


【解决方案1】:

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

push(temp);

可能也应该将stack::display() 重命名为stack::display_and_pop()

【讨论】:

  • 当我删除 push(temp) 时,它允许我处理多个计算,但是当我尝试只做这个输入时,我得到以下输出,而不是 -40 的正确答案。 RPN 计算器:输入 100 10 50 25 / * - -2 / = 错误:操作数过多 错误:操作数过多 输出 80 输出 -0
猜你喜欢
  • 1970-01-01
  • 2016-01-22
  • 1970-01-01
  • 2017-08-18
  • 2014-01-13
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 2020-09-15
相关资源
最近更新 更多