算数的中缀表达式计算

本文介绍了中缀表达式及其与后缀表达式的关系,强调了后缀表达式的顺序读取和计算优势。详细阐述了从中缀表达式转换到后缀表达式的算法过程,使用两个栈st1和st2进行操作,处理操作数和操作符的入栈规则,并指出目前算法仅支持+ - * /四种运算,未包含小数和括号的情况。最后,提供了20190802的更新链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中缀表达式:操作符在操作数中间;例如:1+2*3-4/5
后缀表达式:操作符在操作数后面;例如:1 2 3 * 4 5 / - +
后缀表达式的优点:按顺序读取,碰到操作数进栈;碰到操作符就把前面两个操作数弹出来计算,计算结果进栈;

从中缀表达式到后缀表达式的变换:
栈st1 和栈st2 ,st1 放操作符,st2 放操作数;遍历表达式字符串:
遇到数字:压入st2;
遇到操作符:压入st1中,但是压入之前检查,如果当前栈顶不为空且该操作符优先级高于待入栈的操作符(操作符的优先级可以用map定义),那么就把当前栈顶的操作符出栈压入st2中,直到操作符优先级不高于当前待入栈的操作符。
最后将st1剩余元素依次弹出压入st2中,st2逆序输出即为后缀表达式;

不足:还未实现带小数的操作数识别以及带括号的表达式;
暂时只支持+ - * / 四种表达式。
【更新20190802】传送门

Code:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string> 
#include<vector>
#include<map>
#include<stack>

using namespace std;

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

string str;
stack<node> st1;
stack<node> st2;
stack<node> st3;//后缀表达式 
map<char,int> op; 

double calop(double t1,double t2,char op){
	if(op=='+') return t1+t2;
	if(op=='-') return t1-t2;
	if(op=='*') return t1*t2;
	if(op=='/') return t1/t2;
}

void cal(){
	while(!st2.empty()){
		st3.push(st2.top());
		st2.pop();
	}
	node temp;
	double sum;
	double temp1,temp2;
	char op;
	
	while(!st3.empty()){
		if(st3.top().flag){
			st2.push(st3.top());
			st3.pop();
		}else{
			temp2=st2.top().num;
			st2.pop();
			temp1=st2.top().num;
			st2.pop();
			op=st3.top().op;
			st3.pop();
			sum=calop(temp1,temp2,op);
			temp.flag=true;
			temp.num=sum;
			st2.push(temp);	
		}
	}
	printf("%.2f",st2.top().num);
} 

void change(string str){
	int len=str.length();
	for(int i=0;i<len;i++){
		node temp;
		double num=0;
		if(str[i]<='9'&&str[i]>='0'){
			//是数字
			while(i<len&&str[i]<='9'&&str[i]>='0'){
				num=10*num+str[i]-'0';
				i++;
			}
			temp.num=num;
			temp.flag=true;
			st2.push(temp);
			i--;
		}
		else{
			//是字符
			temp.op=str[i];
			temp.flag=false;
			
			while(!st1.empty()&&op[str[i]]<op[st1.top().op]){
				st2.push(st1.top());
				st1.pop();
			}
			st1.push(temp);
		}
	}
	while(!st1.empty()){
		st2.push(st1.top());
		st1.pop();
	}
}


int main(){
//	freopen("1.txt","r",stdin);
	op['+']=op['-']=1;
	op['*']=op['/']=2;
	cin>>str;
	change(str);
	cal(); 
//	while(!st2.empty()){
//		if(st2.top().flag){
//			printf("%.0f ",st2.top().num);
//			st2.pop();
//		}else{
//			printf("%c ",st2.top().op);
//			st2.pop();
//		}
//	}
	
	
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值