算法笔记_栈_中缀转后缀并计算(无括号)

不知道为什么运算错误??
在这里插入图片描述

中缀转后缀
//需要一个操作符栈,一个后缀表达式队列
后缀计算
//需要一个接收从后缀表达式的计算栈(可重复使用操作符栈)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <cstdio>
#include <map>
#include <iostream>
#include <stack>
#include <queue>
#include <cstring>
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();){//strlen(????)
        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;
            // if(op[temp.op]>op[s.top().op]){
            //     s.push(temp);
            // }else{
                while(op[str[i]]<=op[s.top().op]&&!s.empty()){
                    q.push(s.top());
                    s.pop();
                }
                // if(op[temp.op]>op[s.top().op]){
                //     s.push(temp);
                // }
                temp.op=str[i];
                s.push(temp);
                i++;
            }
          }
            //已经遍历完字符串,但是操作符栈仍有操作符,就把他们弹出到后缀表达式队列中
            while(!s.empty()){
                q.push(s.top());
                s.pop();
        }
}

double cal(){
    double t1,t2;
    node cur,t;
    while(!q.empty()){
        cur = q.front();
        q.pop();
        if(cur.flag==true){//如果是操作数
            s.push(cur);
        }else{//如是操作符
            t1=s.top().num;
            s.pop();
            t2=s.top().num;
            s.pop();
            t.flag=true;
            // switch(cur.op){
            //     case '+':t.num=t2+t1;break;
            //     case '-':t.num=t2-t1;break;
            //     case '*':t.num=t2*t1;break;
            //     case '/':t.num=t2/t1;break;
            // }
            if(cur.op=='+')t.num=t2+t1;
            else if(cur.op=='-')t.num=t2-t1;
            else if(cur.op=='*')t.num=t2*t1;
            else t.num=t2/t1;
            s.push(t);
        }
    }
    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;
}

栈:stack,后进先出的数据结构。
可以把栈理解成一个箱子,而箱子的容量仅供一本书放入或拿出。
每次可以把一本书放在箱子的最上方,也可以把箱子最上方的书拿出。

栈顶指针:始终指向栈的最上方元素的一个标记。
1.当用数组实现栈时,栈顶指针是一个int型的变量(数组下标从0开始),通常记为TOP,int型变量TOP表示栈顶元素的下标;
2.而当链表实现栈时,则是一个int*型的指针;

用数组s[]来实现栈,而int型变量TOP表示栈顶元素的下标(数组下标从0开始),
这样栈中没有元素时(栈空),TOP就是-1。

常见操作:

注意点:
1.出栈操作和取栈顶元素操作必须在栈非空的情况下才能使用,
因此在使用pop()和top()函数之前,必须先使用empty()来判断栈是否为空
2.如果要实现栈的清空,可以用一个while循环反复pop出元素直至栈空或是重新定义一个栈

while(!s.empty()){
	s.pop();
}

STL中的stack实现了栈的常用操作,只需要调用函数就可以了
这样可以更理解程序的逻辑而不是栈的具体实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值