【算法笔记】使用栈(stack)和队列(queue)完成的一个简单计算器(同时求解后缀表达式)

题目描述

读入一个只包含加减乘除的非负整数计算表达式,并求解结果;
本题用来练习栈和队列的使用,核心是中缀表达式转后缀表达式;

输入格式

每次输入一行,整数和运算符之间用一个空格(或者可以不加)分隔;

输出格式

每次输出一行,精确到小数点后 2 位;

输入示例

30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92

输出示例

12178.21

思路

输入的格式为中缀表达式,需要计算结果需要以下两个步骤:

  1. 中缀表达式转后缀表达式;
  2. 计算后缀表达式;

中缀表达式是人类习惯使用的,但是后缀表达式和前缀表达式更适合计算机的计算过程。中缀表达式可以简单的理解为运算符放在两个操作数中间,但后缀表达式的运算符放在两个操作数之后,前缀即放在两个操作数之前,示例如下:

中缀表达式:3 + 2 * 6 / 3
后缀表达式:3 2 6 * 3 / +
前缀表达式:+ 3 / * 2 6 3

本次程序采用中缀表达式转后缀表达式;

中缀表达式转后缀表达式:
  1. 设立一个操作符栈 s ,用于临时存放操作符;设立一个队列 q ,用来存放后缀表达式
  2. 从左到右,扫描中缀表达式,每个字符使用包含操作符 op 、操作数 num 和选择项 flag 的结构体表示。此时需要注意两点:① 操作数可能不止一位,不能只关心个位数;② 操作前需要把中缀表达式中的空格全部删除;
  3. 如果碰到操作数,就将操作数加入后缀表达式 q 的 num 中,并把 flag 设为 true;如果碰到操作符(记为 op),就比较 op 与栈顶操作符 s.top() 的优先级,优先级排序为乘法 == 除法 > 加法 == 减法
  4. op 与 s.top() 优先级的比较规则如下:若 op 优先级大于 s.top(),将 op 压入 s;若 op 优先级小于 s.top(),将 s 栈顶弹出到后缀表达式 q 中,直到 op 的优先级大于 s.top() 或者 s 为空;
  5. 重复上述操作 3 和 4,直到中缀表达式扫描完毕,若 s 中仍有元素,将其依次弹出至 q 中;
计算后缀表达式
  • 从左到右扫描后缀表达式,如果是操作数(flag == true),就压入栈 s,如果是操作符(flag == false),就连续弹出两个操作数 temp2 和 temp1,但需要注意,先弹出的是 temp2,后弹出的是 temp1;
  • 将 temp1 和 temp2 与操作符运算,将计算结果重新压入栈 s,此时需要注意,操作结果需要用 double 型变量,因为除法操作可能出现非整除;
  • 最后,栈 s 中仅剩一个数,这个数就是计算结果;
代码
#include <iostream>
#include <stdio.h>
#include <string>
#include <queue>
#include <stack>
#include <map>
using namespace std;

struct node{
   
	double num; //操作数
	char op; //操作符
	bool flag; //选择操作数or操作符
};

string str; //存放中缀表达式的字符串
stack<node> s; //存放操作符的栈
queue<node> q; //存放后缀表达式
map<char, int> op; // 定义操作符的优先级,加减为1,乘除为2

void abbr(){
    //删除空格
	for(string::iterator it=str.begin();it!=str.end();it++){
   
		if
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值