一、课程设计题目及内容
[问题描述]
  一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是正实数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。引入表达式起始、结束符是为了方便。编程利用“运算符优先法”求算术表达式的值。
[基本要求]
(1) 从键盘或文件读入一个合法的算术表达式,输出正确的结果。
(2) 显示输入序列和栈的变化过程。
(3) 考虑算法的健壮性,当表达式错误时,要给出错误原因的提示。

二、程序中使用的数据结构及主要符号说明
程序中使用了堆栈,其中OPTR为运算符栈(运算符包括‘+’‘-’‘*’‘/’‘(’‘)’‘[’‘]’’{’’}’’#’),OPND为操作数栈(操作数包括‘0’’1’’2’’3’’4’‘5’‘6’‘7’‘8’‘9’)
三、程序流程图和带有注释的源程序

源代码:

#include<iostream>
using namespace std;
typedef struct SNode1//运算符栈链
{char data;struct SNode1* next;
}StackNode1, * Linkstack1;
typedef struct SNode2//数字栈链
{int data;struct SNode2* next;
}StackNode2, * Linkstack2;
void InitStack1(Linkstack1& S)//初始化运算符栈链
{S = NULL;
}
void InitStack2(Linkstack2& S)//初始化数字栈链
{S = NULL;
}
void push1(Linkstack1& S, char ch)//运算符入栈
{Linkstack1 p;p = (Linkstack1)malloc(sizeof(Linkstack1));p->data = ch;p->next = S;S = p;
}
void push2(Linkstack2& S, int ch)//数字入栈
{Linkstack2 p;p = (Linkstack2)malloc(sizeof(Linkstack2));p->data = ch;p->next = S;S = p;
}
char GetTop1(Linkstack1& S)//获得运算符栈栈顶元素
{if (S != NULL)return S->data;
}
int GetTop2(Linkstack2& S)//获得数字符栈栈顶元素
{if (S != NULL)return S->data;
}
void pop1(Linkstack1& S, char& e)//用元素e存储当前运算符栈栈顶元素
{                               //弹出栈顶元素,栈顶指针指向下一元素e = GetTop1(S);if (S != NULL){S = S->next;}
}
void pop2(Linkstack2& S, int& e)//用元素e存储当前数字栈栈顶元素
{                               //弹出栈顶元素,栈顶指针指向下一元素if (S != NULL){e = GetTop2(S);S = S->next;}
}
int In(char ch)//In函数检测字符ch是运算符还是数字
{           //若为运算符,返回1;若为数字,返回0switch (ch){case '(':return 1;case ')':return 1;case '+':return 1;case '-':return 1;case '*':return 1;case '/':return 1;case '#':return 1;case '[':return 1;case ']':return 1;case '{':return 1;case '}':return 1;default: return 0;}
}
char Precede(char a, char b)//比较运算符优先级
{if (b == '+'){if (a == '(' || a == '#' || a == '[' || a == '{')   return '<';return '>';}if (b == '-'){if (a == '(' || a == '#' || a == '[' || a == '{')    return '<';return '>';}if (b == '*'){if (a == '*' || a == '/' || a == ')' || a == ']' || a == '}')    return '>';return '<';}if (b == '/'){if (a == '*' || a == '/' || a == ')' || a == ']' || a == '}')    return '>';return '<';}if (b == '(')  return '<';if (b == ')'){if (a == '(') return '=';return '>';}if (b == '#'){if (a == '#')  return '=';return '>';}if (b == '['){if (a == ')')   return '>';return '<';}if (b == ']'){if (a == '[') return '=';return '>';}if (b == '{'){if (a == ')' || a == ']') return '>';return '<';}if (b == '}'){if (a == '{') return '=';return '>';}
}
int Operate(int a, char op, int b)//根据运算符,进行运算
{switch (op){case '+':return a + b; break;case '-':return a - b; break;case '*':return a * b; break;case '/':return a / b; break;}
}
void Cout_stack1(Linkstack1& S)//输出运算符栈元素
{Linkstack1 T;T = new StackNode1;T = S;if (T == NULL){cout << "运算符栈为空!!";}while (T){cout << T->data << '\t';T = T->next;}cout << endl;
}void Cout_stack2(Linkstack2& S)//输出字符栈元素
{Linkstack2 T;T = new StackNode2;T = S;if (T == NULL){cout << "操作数栈为空!!";}while (T){cout << T->data << '\t';T = T->next;}cout << endl;
}
int EvaluateExpression()
{char theta = 0, x = 0;int a = 0, b = 0;Linkstack1 OPTR;//运算符Linkstack2 OPND;//操作数Linkstack1 q;InitStack1(OPTR);InitStack2(OPND);InitStack1(q);cout << "请输入算术表达式:";push1(OPTR, '#');char ch;cin >> ch;cout << "----------------------------------------" << endl;if (ch == ')' ||ch==']'||ch=='}'|| ch == '+' || ch == '-' || ch == '*' || ch == '/'){cout << "输入错误!!!表达式第一个值不能为运算符" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}cout << "初始运算符栈:";Cout_stack1(OPTR);cout << "初始操作数栈:";Cout_stack2(OPND);cout << "----------------------------------------" << endl;while (ch != '#' || GetTop1(OPTR) != '#'){cout << "输入序列:" << ch << endl;q = OPTR;if (ch != '#' && ch != '0' && ch != '1' && ch != '2' && ch != '3' && ch != '4' && ch != '5' && ch != '6' && ch != '7' && ch != '8' && ch != '9' && ch != '+' && ch != '-' && ch != '*' && ch != '/' && ch != '(' && ch != ')' && ch != '[' && ch != ']' && ch != '{' && ch != '}'){cout << "错误!!!非法输入!!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}//检测非法输入if (ch == ')'){while (q->data != '(' && q->next){q = q->next;}if (q->data != '('){cout << "错误!!!右小括号输入过多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}//括号匹配if (ch == ']'){while (q->data != '[' && q->next){q = q->next;}if (q->data != '['){cout << "错误!!!右中括号输入过多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}//括号匹配if (ch == '}'){while (q->data != '{' && q->next){q = q->next;}if (q->data != '{'){cout << "错误!!!右大括号输入过多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}//括号匹配if (!In(ch))//In函数检测字符ch是运算符还是数字{           //若为运算符,返回1;若为数字,返回0int q = 0;q = ch - 48;int temp, temp1;push2(OPND, q);cin >> ch;cout << "输入序列:" << ch << endl;for (int i = 0; i < 99; i++){if (ch >= 48 && ch <= 57){int l = ch - 48;pop2(OPND, temp);temp1 = temp * 10 + l;push2(OPND, temp1);cin >> ch;cout << "输入序列:" << ch << endl;}}}else{switch (Precede(GetTop1(OPTR), ch))//运算符优先级比较{case'<':push1(OPTR, ch); cin >> ch; break;case'>':pop1(OPTR, theta); pop2(OPND, b);if (OPND == NULL){cout << "错误!!!运算符过多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}//检测运算符是否过多pop2(OPND, a);push2(OPND, Operate(a, theta, b)); break;case'=':pop1(OPTR, x); cin >> ch; break;}}if (ch == '#'){if (q->data == '('){q = q->next;if (q->data == '('){cout << "错误!!!左小括号输入过多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}}//括号匹配if (ch == '#'){if (q->data == '['){q = q->next;if (q->data == '['){cout << "错误!!!左中括号输入过多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}}//括号匹配if (ch == '#'){if (q->data == '{'){q = q->next;if (q->data == '{'){cout << "错误!!!左大括号输入过多!!!" << endl;cout << "----------------------------------------" << endl;cout << endl;cin.ignore(100, '\n');return 77777;}}}//括号匹配cout << "运算符栈:";Cout_stack1(OPTR);cout << "操作数栈:";Cout_stack2(OPND);cout << "----------------------------------------" << endl;}cout << "运算符栈:";Cout_stack1(OPTR);cout << "操作数栈:";Cout_stack2(OPND);cout << "----------------------------------------" << endl;return GetTop2(OPND);
}
int main()
{for (int i = 0; i < 40; i++){cout << "欢迎使用算术表达式计算器!!" << endl;cout << "注意:输入结束时请用#符号结束,否则将使程序崩溃!!!!" << endl;int a = EvaluateExpression();if (a != 77777){cout << "运算结果为:" << a << endl;cout << "----------------------------------------" << endl;cout << endl;}}
}

四、执行程序,并打印程序运行时的初值和运算结果
输入120/{240/[120/(1+1)]}#,程序将进行运算,打印出输入序列,运算符栈和操作数栈里的内容,最后输出运算结果为30


五、实验结果分析,实验收获和体会
考虑到算法的健壮性,考虑各种错误输入时,算法进行判断,并给出错误原因
1、非法输入时,如abcd或!&,系统会自动进行判断

2、括号不匹配时,如左括号过多或者右括号过多,系统也会进行报错,其中包括各种括号()[]{}






3、当输入的运算符过多时,会导致操作数不够用,系统会识别并且报错


六、实验的改进意见和建议
程序还需改进:
1、当用户输入算术表达式时,如果没有输入#,算法不会报错,并且直接进行下去直到识别最后一个字符时才会停止,此时输入#才能继续进行算法.
建议:运用数组先存储输入进去的全部字符,扫描最后一个字符是否为#,若是#才能进行算法;若不是,系统报错,停止算法。
2、算术表达式无法输入负数.
建议:增加对于‘-’(ch=45)的判别函数
3、对于浮点数的运算没有实现.
建议:增加对于‘.’(ch=46)的判别函数

数据结构课程设计:算术表达式的求值相关推荐

  1. C++——算术表达式的求值(数据结构课程设计)

    数据结构课程设计--算术表达式的求值 1.实验目的 1.在课程设计中提高学生的动手能力和编程能力; 2.在课程设计中提高数据结构中理论知识(栈和二叉树等知识)的应用. 3.在课程设计中提高自己对各个方 ...

  2. 【swjtu】数据结构实验2_中缀表达式的求值算法

    实验内容及要求: 从键盘输入中缀表达式,建立操作数与运算符堆栈,计算并输出表达式的求值结果. 基本要求:实现 +, -, *, /四个二元运算符以及():操作数范围为0至9. 提高要求:实现+, -两 ...

  3. 算术表达式字符串求值

    问题: 计算字符串"10+12*13-30/20"的值 思路: 第一步:从左到右解析字符串,将数值与运算符放入数组 第二步:先计算乘除法,将求值放入队列 第三步:依次出队列,计算最 ...

  4. 算术表达式求值的程序设计与实现_数据结构课程设计

    以下内容可且仅可供参考,如有错误欢迎指正. 部分思路借鉴算术表达式求值(C语言栈)_夜何其的博客-CSDN博客_c语言利用栈求解算术表达式侵删致歉 <算术表达式求值的程序设计与实现>题目要 ...

  5. 表达式求值问题数据结构课程设计

    完整代码在最后~~ 1 需求分析 1.1 问题描述 表达式求值是程序设计语言编译中的一个最基本问题,就是将一个表达式转化为逆波兰表达式并求值.具体要求是以字符序列的形式从终端输入语法正确的.不含变量的 ...

  6. c语言中缀表达式求值_[源码和文档分享]基于C++的表达式计算求值

    一.使用说明 1.1 项目简介 表达式求值是程序设计语言编译中的一个最基本的问题,就是将一个表达式转化为逆波兰表达式并求值.具体要求是以字符序列的形式从终端输入语法正确的.不含变量的整数表达式,并利用 ...

  7. c语言程序设计报告表达式求值,数据结构 课程设计表达式求值 实验报告

    <数据结构 课程设计表达式求值 实验报告>由会员分享,可在线阅读,更多相关<数据结构 课程设计表达式求值 实验报告(21页珍藏版)>请在人人文库网上搜索. 1.实验课程名称 级 ...

  8. 数据结构课程设计---------用栈来实现表达式求值

    1.需求分析 设计一个程序,演示用算符优先法对算术表达式求值的过程.利用算符优先关系,实现对算术四则混合运算表达式的求值. (1)输入的形式:表达式,例如2*(3+4)      包含的运算符只能有' ...

  9. 数据结构课程设计之项目三---算术表达式求解

    目录 问题描述 基本要求 问题分析 逻辑设计 物理设计 存储结构 其他模块功能核心函数伪代码 总结 问题描述 设计一个简单的算术表达式计算器. 基本要求 实现标准非负整数类型的四则运算中缀表达式的求值 ...

  10. 数据结构课程设计---赛事统计,校园导航,算术表达式

    文章目录 目录 项目一:计算机设计大赛赛事统计 一.内容与相关要求: 二.问题分析和任务定义: 三.数据结构的选择和概要设计; 3.1 数据结构的选择 3.2 概要设计 3.2.1 功能函数的设计 四 ...

最新文章

  1. python argv 详解_Python3 sys.argv[ ]用法详解
  2. UIActivityViewController使用
  3. C#中用HttpWebRequest/HttpWebResponse来发送/接收数据
  4. 2020年余丙森概率统计强化笔记-第五章 大数定律和中心极限定理 第六章 数理统计
  5. WPFWCFWF打造HelloWorld程序
  6. jcDate时间选取jQuery插件
  7. jre环境变量配置_详解java环境变量意思-用于解决环境搭建问题
  8. UGUI_使用DoTween
  9. python三大主流框架的对比
  10. [TCP/IP] TCP在listen时的参数backlog的意义
  11. hash算法的介绍 【清晰易懂】
  12. Core Foundation 与 cocoa Foundation框架区别
  13. 安装 PrestaShop 1.6 - 详细的安装指南
  14. windows10和安装linux双系统安装教程(超简单)
  15. 2022年6月深圳地区数据分析师认证(CPDA),进入了解
  16. 高频电子线路复习考试题及答案
  17. 蚂蜂窝VS穷游最世界-自由行类App分析
  18. 坚果云企业版服务器端,坚果云企业版常见问题解答
  19. 神经网络是什么,神经网络具体有什么用?
  20. 数析三剑客 numpy pandas matplotlib 基础操作

热门文章

  1. github 上适合java初学者跟的项目
  2. 怎么用计算机录制mp3的音频,内录音频是什么_如何用电脑内录音频图文步骤
  3. POKERNOSE 写字心得(汇总)
  4. 大一下学期,大二上学期,这一年
  5. 常见代码英文词汇缩写
  6. 微信公众号是html页面吗,微信公众号网页开发
  7. 面试官:ca证书存储在哪的
  8. opencv无法打开源文件opencv2/opencv.hpp文件
  9. mysql查看表空间占用情况
  10. rk3568 sensor调试记录