四则运算表达式求值

本文探讨了中缀、前缀和后缀运算表达式,讲解了如何将中缀表达式转换为后缀表达式并进行求值。通过C++代码实现了四则运算表达式的转换和计算,支持浮点数操作。

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

四则运算表达式求值

本文将讨论什么是运算表达式,如何用代码实现中缀表达式转后缀表达式、前缀表达式,以及对后缀表达式的求值。

关于算术表达式

通常我们所看到的算术表达式,运算符总是在两个操作数中间,这样的表达式叫做中缀表达式。与之对应的还有前缀表达式,后缀表达式。中缀表达式易于人的理解,但是使用时往往涉及到运算符的优先级问题,并且需要对括号进行处理。编译系统中对中缀形式的算术表达式的处理方式是: 先把中缀表达式转换成后缀表达式,再进行计算。

表达式的转换和求值方法简述

前缀表达式求值方法
从右往左扫描表达式,遇到数字则压栈,遇到操作符则从栈顶取出两个数进行计算,并将结果压回栈中。

后缀表达式求值方法
方法与前缀表达式求值方法相似,但扫描方向变成从左往右。

中缀表达式求值方法
中缀表达式需要转换成前序表达式或后续表达式。

中缀式转后缀式方法
维护两个栈,运算符栈s1 和 结果栈s2。从左到右扫描表达式。遇到数字直接放s2;遇到操作符时,若:s1为空、自身或s1顶部为’(’、优先级比s1顶部高,则将操作数压入s1,否则将s1顶元素转移到s2,然后继续与最新的s1顶部对比; 若当遇到括号 ‘)’ 时,将s1中第一个’('之前的元素转移到s2中,并丢弃剩余的一对括号。遍历完毕后若s1有剩余则将其转移到s2,s2的逆序弹出结果为对应的后缀表达式。

中缀式转前缀式方法
过程可以参考中缀转后缀的过程,其中差别:
扫描方向是从右往左;
‘(’ 和 ‘)’ 的处理方式要倒转;
与s1顶部对比时,优先级更高或相等都压到s1顶部(之前不包括相等);
最终结果栈的弹出结果不用转逆序;

参考代码:

以下的代码使用C++实现上面提及到的转换和求值过程,支持包括浮点数的四则运算。


#define STRINGS vector<string>	//字符串数组类型别名

//对中缀表达式进行词法分析,分开每个元素放到数组里面,元素包括数字和运算符两大类
//input example: 1+2*3  10.5+((21+34)*4.5)-56.6
STRINGS splitFormula(string formular){
   
	STRINGS result;
	string buf;
	regex reg("\\d+(\\.\\d+)?|[\\+\\-\\*\\/\\(\\)]");
	smatch matchRes;
	while (regex_search(formular, matchRes, reg)){
   
		result.push_back(matchRes.str());
		formular = matchRes.suffix().str();
	}
	return result;
}

//枚举表达式中每项元素的类型
enum eleType{
   IntType, FloatType, OpeType, Unknow};

//判断表达式中元素的类型
eleType judgeType(string ele){
   
	regex numReg("^\\d+$");
	if (regex_match(ele, numReg)){
   
		return IntType;
	}
	regex numReg1("^\\d+(\\.\\d+)?$");
	if (regex_match(ele, numReg1)){
   
		return FloatType;
	}
	regex opeReg("^[\\+\\-\\*\\/\\(\\)]$");
	if (regex_match(ele, opeReg)){
   
		return OpeType;
	}
	return Unknow;
}

//判断操作符的优先级
int getPriority(string ope){
   
	if (ope == "+" || ope == "-"){
   
		return 1;
	}
	if (ope == "*" || ope == "/"){
   
		return 2;
	}
	return 4;
}

//中缀表达式转后缀表达式
STRINGS inFixToSurFix(STRINGS seq){
   
	stack<string> tmpRes, tmpOpe;
	for 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值