The application of the algorithm note stack simple calculator infix and postfix expression

Ideas

  • Convert the entered infix expression to postfix expression
    • When you encounter a number, calculate the value and put it directly into the queue (note that the data is not only one bit, you need to calculate the value of the entire number)
    • When encountering an operator, first determine whether the priority is less than the top operator in the stack
      • If it is, pop the operators in the stack into the queue until there is no operator in the stack with a higher priority
      • If not, put the operator directly on the stack
    • Finally, if there are remaining operators in the stack, they are directly put into the queue
  • Calculate the suffix expression, traverse the queue
    • If it is a number, put it on the stack
    • If it is an operator
      • Pop two numbers from the stack (note that the second is first, then the first, last in first out)
      • Subsequent operations
      • Finally put the calculated number into the stack

Code

#include <iostream>
#include <stdio.h>
#include <stack>
#include <queue>
#include <map>
using namespace std;

struct node{
    
    
    int flag;//区别操作数和操作符
    double num;
    char op;//操作符
};

stack<node> opers;
queue<node> behind;
string middle;
map<char,int> op;

void Change(){
    
    //把中缀表达式转后缀表达式
    for(int i=0;i<middle.length();){
    
    
        node temp;
        temp.flag=1;
        if(middle[i]>='0'&&middle[i]<='9'){
    
    
            temp.num=middle[i]-'0';
            i++;
            while(i<middle.length()&&middle[i]>='0'&&middle[i]<='9'){
    
    
                temp.num=temp.num*10+middle[i]-'0';
                i++;
            }
            behind.push(temp);
        }
        else{
    
    
            temp.flag=0;
            while(!opers.empty()&&op[middle[i]]<=op[opers.top().op]){
    
    //如果操作符优先级低于操作符栈
                behind.push(opers.top());
                opers.pop();
            }
            temp.op=middle[i];
            opers.push(temp);
            i++;
        }
    }
    //如果最后栈中还有操作符,直接压入
    while(!opers.empty()){
    
    
        behind.push(opers.top());
        opers.pop();
    }
}

double Cal(){
    
    //计算后缀表达式
    double temp1,temp2;
    node cur,temp;
    while(!behind.empty()){
    
    
        cur=behind.front();//记录队首元素
        behind.pop();
        if(cur.flag==1)//是数
            opers.push(cur);
        else{
    
    
            temp2=opers.top().num;
            opers.pop();
            temp1=opers.top().num;
            opers.pop();
            temp.flag=1;
            if(cur.op=='+') temp.num=temp1+temp2;
            else if(cur.op=='-') temp.num=temp1-temp2;
            else if(cur.op=='*') temp.num=temp1*temp2;
            else temp.num=temp1/temp2;
            opers.push(temp);
        }
    }
    return opers.top().num;
}

int main(){
    
    
    op['+']=op['-']=1;
    op['*']=op['/']=2;
    while(getline(cin,middle)&&middle!="0"){
    
    
        //注意从右到左遍历
        for(string::iterator it=middle.end(); it!=middle.begin();it--){
    
    
            if(*it==' ')//忽略空格键
                middle.erase(it);
        }
        while(!opers.empty())   opers.pop();//初始化栈
        Change();
        printf("%.2lf\n",Cal());
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/Cindy_00/article/details/108955215