La aplicación del algoritmo pila de notas calculadora simple infijo y postfijo expresión

Ideas

  • Convierta la expresión de infijo ingresada en expresión de sufijo
    • Cuando encuentre un número, calcule el valor y colóquelo directamente en la cola (tenga en cuenta que los datos no son solo un bit, debe calcular el valor del número completo)
    • Al encontrar un operador, primero determine si la prioridad es menor que el operador superior en la pila
      • Si es así, coloque los operadores de la pila en la cola hasta que no haya ningún operador en la pila con una prioridad más alta.
      • Si no, coloque el operador directamente en la pila
    • Finalmente, si quedan operadores en la pila, se colocan directamente en la cola.
  • Calcula la expresión del sufijo, recorre la cola
    • Si es un número, póngalo en la pila.
    • Si es un operador
      • Saque dos números de la pila (tenga en cuenta que el segundo es el primero, luego el primero, el último en entrar primero en salir)
      • Operaciones posteriores
      • Finalmente, ponga el número calculado en la pila.

Código

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

Supongo que te gusta

Origin blog.csdn.net/Cindy_00/article/details/108955215
Recomendado
Clasificación