【C++数据结构】栈实现简单计算器(类模板)

目录

前言:

一、计算思路及方法 

1.表达式读取及存放 

2.存放顺序和运算规则

二、代码实现

1.创建结点

2.创建栈

3.创建计算器

(1)判断优先级

(2)判断数字并读取

(3)读取运算符

 (4)运算函数

(5)执行运算

4.main函数

三、完整代码  


前言:

        的重要应用之一是表达式求值。本文以简单算术表达式为例展现这一应用。


提示:以下是本篇文章正文内容,代码注释较为详细,可供参考 

一、计算思路及方法 

1.表达式读取及存放 

        算术表达式可分为两部分:数字和运算符。例如有下列表达式:

        a-b/c+d*e;

        为了计算上述表达式的值,可以使用两个栈:一个数据栈和一个运算符栈。其中数据栈用于存放操作数(数字),运算符栈存放运算符。

2.存放顺序和运算规则

        首先从左到右扫描表达式,遇到操作数时,将其压入操作数栈;遇到运算符时。与当前运算符栈的栈顶运算符比较优先级,若高于栈顶运算符优先级运算符栈为空,则将其压入运算符栈否则将栈顶运算符弹出,并根据所弹出运算符的目数,弹出运算数栈中相应数目的操作数(例如“+”是耳目运算符,弹出两个运算数,而“sin”是一目,弹出一个)。然后做运算并将运算结果压入操作数栈重复这一过程,直到当前运算符入栈(运算符栈内没有比当前运算符优先级高的其他运算符)。

        继续扫描表达式,并执行相应操作,直到表达式结束。最后,如果两个栈非空,则逐个弹出运算符栈顶元素和操作符栈中相应数目的运算数,并执行相应运算,将结果压入操作数栈,重复此过程直到运算符栈为空,最后一次运算的结果便是表达式的值。

        上述表达式 a-b/c+d*e的计算过程如下图所示:

        从左到右扫描上述表达式。为了方便,运算符栈初始化一个优先级很低的符号 # 根据上述操作规则 a 入操作数栈,运算符 - 入运算符栈, b 入操作数栈,运算符 / 的优先级高于栈顶运算符 - 的优先级,将其入继续扫描, c 操作数栈,运算符 + 的优先级低于运算符 / 的优先级,因此将运算符 / 弹出,并将两个操作数 c b 依次弹出,做除法运算:b / c,将结果 t1 压入操作数栈。继续比较运算符 + 与栈顶运算符 - 的优先级,运算符 + 的优先级不高于运算符 - ,因此继续将操作数栈中的两个操作数 t1a 弹出,做减法运算:a - t1,将结果 t2

                

        此时运算符已为初始状态,将运算符 + 压入运算符栈。继续扫描, d操作数栈运算符 * 的优先级高于栈顶运算符 + 的优先级,将其压入运算符栈。继续扫描, e 操作数栈,此时表达式扫描完毕(指针指向运算符 = )逐个弹出运算符栈中的元素并执行相应操作:将 * 弹出, e d 出栈,做乘法运算: d * e ,将结果 t3 压栈,最后将运算符 + 弹出 t3 和 t2 出栈,做加法运算: t2 + t3,所得结果 t4 便是上述表达式的值

        ()括号优先级最高且比较特殊,这里这样实现:遇到“(  ”时将其压入运算符栈,当遇到“ )”时,依次弹出运算符栈顶元素并进行相应目数计算,将计算结果压栈,重复上述操作,直到栈顶元素为“(  ”停止并将“(  ”出栈,至此完成“(  ) ”内的运算。

        对于sin,cos这样函数的运算符,我们将其识别后可以规定一个字母代替其(比如“ s ”代表“ sin ”,“ c ”代表“ cos ”,将其压入运算符栈然后将扫描指针跳过其剩余长度的扫描。

        注意,为了保证算术运算符的左结合性,若当前运算符与栈顶运算符优先级相同,则将栈顶运算符弹出,执行相应运算。另外,对于双目运算符,在执行运算时首先弹出的操作数为运算符的右操作数,其后弹出的数为左操作数,如 b / c的运算过程。 

二、代码实现

1.创建结点

        关于结点的建立就不赘述了,这里要注意的是后面要用到的类模板Stack要先提前声明,否则在Node类里声明友元时会报错

#include <cmath>
#include <string>
#include <iostream>
using namespace std;
template<class T> class Stack;
template<class T>
class Node {
private:
    T m_data;//数据域
    Node* m_next = nullptr;/
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值