2015-08-28 40 views
-1

我在计算RPN计算器时遇到了困难,我们必须使用链接列表来执行此任务。 (我已经完成了使用stack<double>方法分配,但它使用链表是使用链接列表的RPN

我有一些麻烦的错误检查:

太多的运营商(+ -/*) 太多。操作数(双精度) 除零除

程序应该继续执行和计算表达式,直到用户在一行中输入一个零(0),然后是一个新行,我也遇到了一些麻烦这是因为我把错误检查放在“太多操作数”中,它不会允许我做第二个计算,OU TPUT将“操作数过多”

我似乎无法得到一个错误检查为“太多的运营商”

我尝试了好几种不同的东西需要的错误检查,看着许多其他工作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; 
    } 
} 
+0

我不确定它是否解决了这个问题,但是尝试在循环中移动'RPN计算器;'。我认为最后一次迭代的结果正在绊倒它。 (另外,'>>'跳过空格,所以你将永远不会读'0 \ n“')。 – molbdnilo

回答

0

问题是,你总是把计算结果留在堆栈上。所以当你做第二次计算时,你并没有从一个空的堆栈开始。简单的解决方法是删除这一行stack::display()

push(temp); 

或许应该改名stack::display()stack::display_and_pop()为好。

+0

当我删除push(temp)时,它允许我处理多个计算,但是当我尝试这样做时输入,我得到以下输出,而不是-40的正确答案。 RPN计算器: 输入 100 10 50 25/* - -2/= 错误:操作数过多 错误:操作数过多 输出输出 -0 – groot