C++ 数据结构 算数表达式求值——栈存储

数据结构实习——算术表达式求值

一、实习题目及要求

1、题目:算术表达式求值
2、要求:
(1)正确解释表达式;
(2)符合四则运算规则:
(3)先乘除、后加减;
(4)从左到右运算;
(5)先括号内,后括号外;
(6)输出最后的计算结果。

二、问题描述

1、对一个合法的中缀表达式求值。
2、假设表达式只包含+、-、*、/ 四个双目运算符,并且允许有括号出现,运算符本身不具有二义性。

三、问题分析

1、本题要求我们计算算数表达式的值,在程序中需要大量的重复运用栈的基本操作。而在程序设计过程需要考虑到运算符的优先级,并需要熟悉栈的操作从而进行计算 。
2、表达式可看做是一个字符串,其中字符分为操作数和运算符两类,因此需要两个工作栈,命名为OPTR(运算符栈)和OPND(操作数栈)。以此判断字符串中的字符,如果是操作数则压入操作数栈,如果是运算符栈,则压入运算符栈,然后再进行弹栈操作。
3、本题还需考虑到小数问题,即把小数点之后的数字和之前的数字分开处理,然后再一同压入栈中。
4、此外还需考虑到负数问题,在输入命令时,负数需要添加括号,通过扫描,当字符串中的字符前一位时‘)’后一位时‘-’时,则需要在操作数栈中先压入一个数0,然后再进行后续的运算,记得实现负数的运算。

四、设计思想

1、本题我首先设计了一个判断运算优先级的函数char Precede(char a, char b)该函数参考老师给的ppt里的代码,并进行了细微的改动。
2、然后定义了函数bool Operate(double a, char theta, double b, double &r),用于计算二元表达式的值,这里需要注意,当除数为零的时候应该返回错误信息,并提醒用户,所以这里我把该函数定义成bool型。
3、在压栈的时候需虑到,字符串中的字符是那种类型,如果是运算符,则需要压进运算栈,如果是操作数,则压进操作数栈,此时,则需要编写一个函数进行字符类型的判断,这里,我编写了一个函数bool IsOperator(char ch),用于判断字符ch是否为运算符,如果是运算符在后面压栈的时候则压进运算符栈,如果不是,而是操作数则压入操作数栈。
4、除了需要判断字符是何种类型之外,还需要判断的是,我们在输入表达式时,输入的括号是否配对,如果配对的话,则可以继续计算,如果不能配对的话,则需提醒用户,为了实现该功能,我便编写了函数bool Check(char s[])用于检查括号是否配对。
接下来则是最重要的,设计具体的计算函数,这里我编写了一个bool Calculate(char s[], double &result) 函数,用于计算表达式结果,在函数的定义过程中,我把函数的类型定义成了bool型,是因为我该函数的编写过程中,我调用了前面编写的bool型的计算二元表达式值得函数,从而在后续函数调用(计算)时能够实现计算并判断函数是否符合规则,即判断当计算除法时,除数是否为0;首先,当遇到小数点得时候,则需要把小数点之后的数字和之前的数字分开处理,用point标记出现小数点后第x位,在继续查找记录数字, 至运算符结束。整数部分为num = num * 10 + (s[j] - 48),即非小数时num = num * 10 + (s[j] - 48);这里由于输入得数属于字符型,根据ascll码把字符串的数减去48即使我们需要计算的数。
然后判断输入的字符是否时运算符,然后根据运算符的优先级进行压栈,然后把操纵数压入操作数栈,再进行弹栈计算,这里,进行是否是负数的判断,如果字符是‘)’且它的后一位是‘-’,则需要往操作数栈里先压入一个0,然后再进行后续计算,则可以实现负数的运算。
5、在主函数中,即要求输入表达式之后,需要转换成规格化表达式,补“/0”和“=”。

五、设计流程图

在这里插入图片描述

六、附录

【源代码】

#include "stdafx.h"
#include <cmath>
#include <stack>
#include <string>
#include<iostream>
using namespace std;

//判断运算符优先级
char Precede(char a, char b) {
    //判断运算符优先级
	int i, j;
	char Table[8][8] = {
   
		{
    ' ', '+', '-', '*', '/', '(', ')', '=' },
		{
    '+', '>', '>', '<', '<', '<', '>', '>' },
		{
    '-', '>', '>', '<', '<', '<', '>', '>' },
		{
    '*', '>', '>', '>', '>', '<', '>', '>' },
		{
    '/', '>', '>', '>', '>', '<', '>', '>' }
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值