中缀表达式求值 -- C++标准库的应用

基本思路

一、中缀表达式求值分两大步:
  • 1、将中缀表达式转换为后缀表达式,统一形式,用空格做间隔;
  • 2、后缀表达式求值。
二、中缀表达式转换为后缀表达式的思路
  • 1、处理空格:输入可能不规范,统一将空格全部删除;此时运算符和括号成为数字的间隔符,方便处理。

  • 2、处理单目运算符正负号±;因为它是单目运算符,运算等级要高,使用!来代表-;+号则忽略

  • 3、查找运算符及间隔符

    • A、运算符不是第一个,则表达式第一个是运算数,运算数直接加入后缀表达式;
    • B、运算符是第一个,则要处理运算符:
      • B.1、第一个可定是运算符,根据优先等级,确认之前的预备运算符是否出栈,
      • B.2、将新的运算符入栈(由于这个有好几种情况需要分情况处理)
      • B.3、如果有左括号,左括号右面~标记一下,查找对应的右括号,递归调用运算符处理函数
    • C、直到中缀表达式的结尾为止。结尾处用空格来区分。
    • D、如果是第一个,而没有有效的运算符,那么就到结尾了
  • 4、关于()的循环:

    • A、遇到(,则从(的下一个字符开始,递归调用中缀转换为后缀的函数。
    • B、遇到), 则跳出当前的递归层。
三、后缀表达式的求值
  • 1、将后缀表达式的内容,根据类型压栈和出栈:
    如果为数值则压栈;
    如果为运算符,则将运算符对应的运算数出栈;计算结果压栈。
  • 2、重复此过程,直到表达式读取结束,此时栈内有一个数,即为结果。
四、定义一个全局unorder_map,用来记录不同运算符的优先级。

程序主体:

#include<stack>
#include<string>
#include<iostream>
#include<sstream>
#include<vector>
#include<functional>
#include<unordered_map>
#include<cmath>
using std::unordered_map;	
using std::function;
using std::string;
using std::stack;
using std::cin;
using std::cout;
using std::endl;
using std::vector;

//使用类型别名,方便处理不同的类型
typedef double ValueType;
//定义基本的函数操作 加、减、乘、除及指数运算;此处使用了lambd表达式和函数
auto add = [](const ValueType &lhs, const ValueType &rhs)->ValueType {
    return lhs + rhs; };
auto minus = [](const ValueType &lhs, const ValueType &rhs)->ValueType {
    return lhs - rhs; };
auto multi = [](const ValueType &lhs, const ValueType &rhs) {
    return lhs * rhs; };
ValueType divide(const ValueType &lhs, const ValueType &rhs) {
   
	if (rhs == 0)
	{
   
		throw std::exception("Divisor is zero.");
		return 0;
	}
	else
		return (rhs / lhs);
}

//定义函数调用的字典,使用了可调用对象
 unordered_map<char, function<ValueType(const ValueType&,const ValueType&)>> Binops = {
   
	{
   '+',add},{
   '-',minus},{
   '*', multi},{
   '/',divide},{
   '^',std::powl
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于中缀表达式求值,一般需要借助栈来完成。具体的步骤如下: 1. 创建一个运算符栈和一个操作数栈。 2. 从左到右遍历中缀表达式的每一个元素。 - 如果当前元素是操作数,直接将其压入操作数栈。 - 如果当前元素是运算符,分为以下几种情况处理: - 如果运算符栈为空或者栈顶运算符是"(",则直接将该运算符压入运算符栈。 - 如果当前运算符的优先级大于栈顶运算符的优先级,将当前运算符压入运算符栈。 - 如果当前运算符的优先级小于或等于栈顶运算符的优先级,将栈顶运算符弹出,并将其与操作数栈栈顶的两个操作数进行计算,将计算结果压入操作数栈,并将当前运算符压入运算符栈。重复这一步骤直到当前运算符的优先级大于栈顶运算符的优先级。 - 如果当前运算符为")",则依次弹出运算符栈的栈顶元素,直到栈顶元素为"("。将弹出的运算符与操作数栈栈顶的两个操作数进行计算,将计算结果压入操作数栈。 3. 遍历完中缀表达式后,将运算符栈中的剩余运算符依次弹出,并对操作数栈栈顶的两个操作数进行计算,将计算结果压入操作数栈。 4. 遍历完后,将操作数栈中的唯一元素即为中缀表达式的求值结果。 需要注意的是,对于乘法和除法这样的高优先级运算符,要先进行计算再进行压栈操作,而对于加法和减法这样的低优先级运算符,只有在栈顶运算符优先级小于当前运算符时才进行计算。 这就是中缀表达式求值的基本步骤。通过按照以上步骤运算,可以得到中缀表达式c的求值结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值