数据结构课程设计-项目三-算术表达式求解(实验准备)


一.问题描述

设计一个简单的算术表达式计算器。

二.基本要求

实现标准整数类型的四则运算表达式的求值(包含括号,可多层嵌入)。

三.问题分析

【功能分析】

要把一个表达式翻译成正确求值的机器指令序列,或者直接对表达式求值,首先要正确解释表达式。
表达示求值应按照下述算数四则运算法则来进行运算:
(1)先乘除,后加减
(2)从左到右计算
(3)先括号内,后括号外

【基本思想】

由于用户输入的算数表达式是中缀表达式,不利于机器的自动求解。而我们知道在语法扫描分析等应用场合我们一般采用后缀表达式(逆波兰式)做运算。对逆波兰式求值只需从左到右扫描,遇到操作符就将左边的两个操作数进行计算,直到整个式子扫描结束为止。

【数据结构的选取】

我们将算数表达式中的字符分为操作数和运算符,运算符包括算数运算符{‘+’,‘-’,‘*’,‘/’}和算数界限符{左括号’(‘,右括号’)‘,定界符’=‘,’#'}。我们可以建立两个栈结构操作数栈s和操作符栈chs,操作数栈s用于存放操作数,操作符栈chs用于存放操作符。

四.逻辑设计

【模块划分】

1.两个操作数运算模块
2.栈内运算符优先级模块
3.栈外运算符优先级模块
4.中缀表达式转逆波兰式模块
5.计算逆波兰式模块

【抽象数据结构ADT】
ADT	算数表达式求解
	Data
	  操作数栈s
	  操作符栈chs
	Operation
	  操作数栈顶的两个元素的运算
	    输入:运算符oper
	    功能:将操作数栈顶的两个元素取出做oper运算并重新压入操作数栈中
	    输出:无
	   栈内运算符优先级赋值
	     输入:栈外运算符
	     功能:为栈外运算符优先级赋值
	     输出:该运算符的优先级
	   栈内运算符优先级赋值
	     输入:栈内运算符
	     功能:为栈内运算符优先级赋值
	     输出:该运算符的优先级
	  中缀表达式转后缀表达式
	    输入:中缀表达书
	    功能,将中缀表达式转换为逆波兰式并将操作符相应地压入操作符栈
	    输出:后缀表达式
	  计算后缀表达式
	    输入:后缀表达式
	    功能:通过后缀表达式计算出算数表达式的结果
	    输出:算数表达式的求解结果
endADT 

五.物理设计

【存储结构】

1.开辟两个栈结构分别用来存储运算数和操作符
2.用一个txt文件来存储中缀表达式和后缀表达式,以便于写入和读取

【函数设计】

1.栈顶两个操作数运算设计

伪代码:
1.弹出操作数栈的栈顶两个元素
2.将第一个弹出的元素作为右操作数,第二个弹出的元素作为左操作数
3.根据参数给定的运算符对两个操作数进行运算并压入操作数栈中

2.栈内运算符优先级赋值设计

//求操作符栈内栈顶元素的优先级
int Calculator::inp(char ch) {
    switch (ch) {
        case'(': return 1;
        case'*': return 3;
        case'/': return 3;
        case'+': return 2;
        case'-': return 2;
        case'#': return 0;
        default: cout << "有不可识别的运算符 !" << endl;
            exit(0);
    }      
}

3.栈外运算符优先级赋值设计

//求栈外(当前扫描到的操作符)的优先级
int Calculator::outp(char ch) {
    switch (ch) {
        case'(': return 5; break;
        case'*': return 3; break;
        case'/': return 3; break;
        case'+': return 2; break;
        case'-': return 2; break;
        case'#': return 0; break;
        default: cout << "有不可识别的运算符!" << endl;
            exit(0);
    }
}

4.中缀表达式转逆波兰式设计

伪代码:
1.通过键盘一个字符一个字符地读取输入的中缀表达式并以等号结束输入
2.若读到数值,将该数值放回,重新用double变量读取整体数值并写入文件(数值写入时候用"|"分隔)
3.若遇右括号,则将运算符栈中左括号后压入的运算符弹出并写入文件
4.若遇左括号,判断括号内是否为负数
5.对于其余运算符,若当前扫面的运算符优先级大于栈顶运算符优先级,则将压入栈顶。
  若小于栈顶运算符优先级,则将大于栈外运算符优先级的栈内元素全部弹出写入文件。
6.读取完毕后,将操作符栈中的运算符全部弹出写入文件

5.逆波兰式求解算数表达式设计

伪代码:
1.从文件中读取逆波兰式(以#为结束符)
2.当遇到分隔符'|'时,读取一个doule,并将其压入操作数栈中
3.当遇到加减乘除的运算符,则调用栈顶两个操作数运算函数求解
【函数算法框架】

函数调用关系图

六.测试数据

(30+2* 70)/3-12* 3=
5+(9*(62-37)+15)*6=
要求自行设计非法表达式,进行程序测试,以保证程序的稳定运行。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值