课程实践实验2:中缀表达式求值
问题描述及要求
中缀表达式是我们熟悉的表达式形式。为了能正确表示运算的先后顺序,中缀表达式中难免要出现括号。假设我们的表达式中只允许有圆括号。
读入一个浮点数为操作数的中缀表达式后,对该表达式进行运算。
要求中缀表达式以一个字符串的形式读入,可含有加、减、乘、除运算符和左、右括号,并假设该表达式以“#”作为输入结束符。
如输入“3.5*(20+4)-1#”,则程序运行结果应为83。
要求可单步显示输入序列和栈的变化过程。并考虑算法的健壮性,当表达式错误时,要给出错误原因的提示。
概要设计
(1) 对实验内容的理解和二次概括。
通过输入中缀表达式,对其字符串进行操作,转化为后缀表达式,并将其压入栈中,便于编程计算,最终可以得出结果。
(2) 给出系统的功能列表(可以用图示或清单的形式)
1.用户可按照正确方法输入中缀表达式。
2.系统能够识别中缀表达式。
3.系统能够计算正确的中缀表达式并输出结果。
4.如表达式含有错误,可识别并提示用户错误。
(3)程序运行的界面设计 (可以用图示等方式,如:首先出现屏幕提示,请用户选择输入配置的方式,1从键盘输入活单元坐标2……3….然后用户)
(4)确定总体设计思路,采用何种数据结构,设计哪些类,各类的作用 ,类方法的介绍,类之间的关系描述
使用堆栈结构来处理表达式,并且设计三个函数分别负责转换表达式,通过后缀表达式计算值和检查算式是否错误。
(5)程序结构设计,包括:对已有程序的使用,自己将设计哪些程序文件,各部分关系描述。
这部分最核心的工作是:描述解决问题所需用到的数据结构和算法。——给出明确地确定该结构及对应算法的理由。
解决此问题,我采用了定义类的方式,将生命游戏中的多种操作定义为类中的函数,这样可以确保每个操作前后联系紧密,也使代码更具系统性,便于管理
详细设计
附代码:
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
using namespace std;
string midfixtopostfix(string &s)
{
int i = 0;
stack<char> symbols;
string output = "";
while (s[i] != '#') //从整个表达式开头一个字一个字开始循环,直到#
{
if (isdigit(s[i]) || s[i] == '.') //如果是数字
{
output += s[i]; //把这个数字加进output的字符串里
if (!(isdigit(s[i + 1]) || s[i + 1] == '.')) output += ' '; //如果下一位不是数字或者小数点 就在输出字符串里加上一个空格 表示这个数字已经结尾了
}
else if (s[i] == '*' || s[i] == '/') //如果是*或/
{
while (!symbols.empty())
{
if (symbols.top() == '*' || symbols.top() == '/')//检查栈顶是否也是*或/
{
output += symbols.top();//如果是,把栈顶元素弹出,并加入输出字符串,再把新来的*或/压入栈中
output += ' ';
symbols.