Algorithm 10 - c++ implements infix expression calculation

Title description:
  Read in a non-negative integer calculation expression containing only +,-,x,/, and calculate the value of the expression

Input format:
  The test input contains several test cases, each test case occupies one line, each line does not exceed 200 characters, and integers and operators are separated by a space. There are no illegal expressions. When there is only 0 in a line, the input ends, and the corresponding result does not need to be output

Output format:
  Output one line for each test case, that is, the value of the expression, accurate to two decimal places

Sample input:

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

Sample output:

12178.21

Ideas:

  • Infix expression to postfix expression
  • evaluate postfix expressions

Infix expression to postfix expression:

  • Set up an operator stack to temporarily store operators; set up an array or queue to store postfix expressions
  • Scan the infix expression from left to right, if an operand is encountered (note: the operand may be more than one), add the operand to the infix expression
  • If the operator op is encountered, op is compared with the priority of the top operator on the stack. If the priority of op is higher than the priority of the operator at the top of the stack, then op will be pushed into the operator stack; otherwise, the operator stack will continue to pop the operator and add it to the postfix expression until the priority of op is higher than the operation at the top of the stack. operator priority, and then push the top operator onto the operator stack
  • Repeat the above operations until the infix expression is scanned, and if there are still elements in the operator stack, pop them up and add them to the suffix expression in turn

Evaluate postfix expressions:

  Scan the suffix expression from left to right, if it is an operand, it will be pushed onto the stack; if it is an operator, the operands will be popped continuously (the second operand is popped first, and the first operand is popped later), and then Perform the operation of the operator, generate a new operand and push it on the stack. Until the postfix expression is scanned, this is the last result that will only exist on the stack

code:

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

Guess you like

Origin blog.csdn.net/weixin_46025531/article/details/122808963