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

本文介绍了中缀表达式转换为后缀表达式的方法,包括处理空格、单目运算符、运算符优先级,以及利用C++标准库实现。通过后缀表达式求值得到计算结果,同时利用全局unordered_map存储运算符优先级。
摘要由CSDN通过智能技术生成

基本思路

一、中缀表达式求值分两大步:
  • 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值