Algoritmo 10: c ++ implementa el cálculo de expresiones infijas

Descripción del título:
  lea una expresión de cálculo de enteros no negativos que contenga solo +,-,x,/, y calcule el valor de la expresión

Formato de entrada:
  la entrada de prueba contiene varios casos de prueba, cada caso de prueba ocupa una línea, cada línea no supera los 200 caracteres y los números enteros y los operadores están separados por un espacio. No hay expresiones ilegales. Cuando solo hay 0 en una línea, la entrada finaliza y no es necesario generar el resultado correspondiente

Formato de salida:
  genera una línea para cada caso de prueba, es decir, el valor de la expresión, con una precisión de dos decimales

Ejemplo de entrada:

30/90-26+97-5-6-13/88*6+51/29+79*87+57*92
0

Salida de muestra:

12178.21

Ideas:

  • Expresión de infijo a expresión de sufijo
  • evaluar expresiones de postfijo

Expresión de infijo a expresión de sufijo:

  • Configure una pila de operadores para almacenar operadores temporalmente; configure una matriz o cola para almacenar expresiones de postfijo
  • Escanee la expresión infija de izquierda a derecha, si se encuentra un operando (nota: el operando puede ser más de uno), agregue el operando a la expresión infija
  • Si se encuentra el operador op, op se compara con la prioridad del operador superior en la pila. Si la prioridad de op es más alta que la prioridad del operador en la parte superior de la pila, entonces op se insertará en la pila de operadores; de lo contrario, la pila de operadores continuará extrayendo el operador y agregándolo a la expresión de posfijo hasta que la la prioridad de la operación es más alta que la operación en la parte superior de la pila.
  • Repita las operaciones anteriores hasta que se escanee la expresión de infijo, y si todavía hay elementos en la pila de operadores, ábralos y agréguelos a la expresión de sufijo a su vez.

Evaluar expresiones de postfijo:

  Escanee la expresión de sufijo de izquierda a derecha, si es un operando, se colocará en la pila; si es un operador, los operandos se extraerán continuamente (el segundo operando se extrae primero y el primer operando se extrae después ), y luego realice la operación del operador, genere un nuevo operando y empújelo a la pila. Hasta que se escanee la expresión de sufijo, este es el último resultado que solo existirá en la pila

código:

#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
#include<queue>
#include<map>
using namespace std;

struct node{
    double num;//操作数
    char op;//操作符
    bool flag;//true表示操作数,false表示操作符
};

string str;
stack<node> s;//操作符栈
queue<node> q;//后缀表达式序列
map<char,int> op;

void Change(){//中缀表达式转后缀表达式
    double num;
    node temp;
    for(int i = 0 ; i < str.length();){
        if(str[i]>='0'&&str[i]<='9'){
            //如果是数字
            temp.flag = true;
            temp.num = str[i++]-'0';
            while(i<str.length()&&str[i]>='0'&&str[i]<='9'){
                //后面一位还是数字,说明这个数还没取完
                temp.num = temp.num*10+(str[i]-'0');
                i++;
            }
            q.push(temp);//加入后缀表达式序列
        }else{
            //如果是操作符
            temp.flag = false;
            //只要操作符栈的栈顶元素比该操作符优先级高
            //就把操作符栈栈顶元素弹出加入到后缀表达式
            while(!s.empty()&&op[str[i]]<=op[s.top().op]){
                q.push(s.top());
                s.pop();
            }
            temp.op = str[i];
            s.push(temp);
            i++;
        }
    }
    //如果操作符栈中还有操作符,就将它弹出加入后缀表达式
    while(!s.empty()){
        q.push(s.top());
        s.pop();
    }
}

 double Cal(){
        //计算后缀表达式
        double temp1,temp2;
        node cur,temp;
        while(!q.empty()){
            cur = q.front();//记录队首元素
            q.pop();
            if(cur.flag==true){
                //如果是操作数,直接压入栈
                s.push(cur);
            }else{
                temp2 = s.top().num;//第二个操作数
                s.pop();
                temp1 = s.top().num;//第一个操作数
                s.pop();
                temp.flag = true;//标记临时操作数
                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;
                s.push(temp);
            }
        }
        return s.top().num;
}

int main(){
    op['+'] = op['-'] = 1;
    op['*'] = op['/'] = 2;
    while(getline(cin,str),str!="0"){
        for(string::iterator it = str.end();it!=str.begin();it--){
            if(*it == ' ')
                str.erase(it);//把表达式中的空格删除
        }
        while(!s.empty())
            s.pop();//初始化栈
        Change();
        printf("%.2f\n",Cal());
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_46025531/article/details/122808963
Recomendado
Clasificación