C++——算术表达式的求值(数据结构课程设计)
数据结构课程设计——算术表达式的求值
1.实验目的
1.在课程设计中提高学生的动手能力和编程能力;
2.在课程设计中提高数据结构中理论知识(栈和二叉树等知识)的应用。
3.在课程设计中提高自己对各个方面知识的综合能力。
2.实验内容
一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是正实数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。引入表达式起始、结束符是为了方便。编程利用“运算符优先法”求算术表达式的值。
3.实验原理
1.设计建立二叉树的头文件(BiTree.h);
2.设计程序中需要用到的栈的相关头文件(Stack.h);
3.设计一个函数去判断符号的优先级(StrPriority());
4.设计函数去判断是否输入的字符是否为运算符或者界符(Is_Operator());
5.通过输入的字符串数组去建立表达式树(InitExpTree());
6.设计一个函数去实现运算(GetStrValue());
7.设计一个函数去将输入的数字型的字符串转换成Double型(ToNumber());
8.设计一个函数去实现通过二叉树遍历进行运算结果求值(EvalateExpTree());
9.为了保证程序的健壮性,根据可能的错误可能性全部错误结果进行打印错误类型(ErrorTest());
10.为了判断是否要打印最终的结果,定义了一个标志Is_Success去进行判断。
4.实验设备
Win10计算机一台
5.实验要求
(1) 从键盘或文件读入一个合法的算术表达式,输出正确的结果。
(2) 显示输入序列和栈的变化过程。
(3) 考虑算法的健壮性,当表达式错误时,要给出错误原因的提示。
6.实验程序
1.创建二叉树的头文件(BiTree.h)
#pragma once
#include <string>
using namespace std;
typedef struct BiTNode
{char opstr; //结点符号域string number; //结点数据域BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode,*BiTree;
void CreateExpTree_Op(BiTree &T, BiTree a, BiTree b, char theta)//a是左孩子,b是右孩子,theta是符号域
{BiTree L = new BiTNode;L->opstr = theta;L->lchild = a;L->rchild = b;T = L;
}void CreateExpTree_Number(BiTree &T, BiTree a, BiTree b, string theta)//a是左孩子,b是右孩子,theta是数字域
{BiTree L = new BiTNode;L->number = theta;L->lchild = a;L->rchild = b;T = L;
}
2.用于建立栈的头文件(Stack.h)
#pragma once
#include"BiTree.h"
#include"Stack.h"
typedef struct StackNode
{BiTree Tree; //存储的是二叉树char Operator; //存储的是符号StackNode *next;
}StackNode,*LinkStack;int InitStack(LinkStack &S) //栈的初始化
{S = NULL;return 1;
}int Push_EXPT(LinkStack &S, BiTree e) //二叉树入栈
{LinkStack p = new StackNode;p->Tree = e;p->next = S;S = p;return 1;
}int Push_OPTR(LinkStack &S, char e) //运算符入栈
{LinkStack p = new StackNode;p->Operator = e;p->next = S;S = p;return 1;
}int Pop_EXPT(LinkStack &S, BiTree &T1) //二叉树出栈
{if (S == NULL) return 0;LinkStack p = S;T1 = p->Tree;S = S->next;delete p;return 1;
}int Pop_OPTR(LinkStack &S, char &ch) //运算符出栈
{if (S == NULL) return 0;LinkStack p = S;ch = p->Operator;S = S->next;delete p;return 1;
}char GetTop_OPTR(LinkStack S)//取栈顶符号
{if (S != NULL) return S->Operator;else return ' ';
}BiTree GetTop_EXPT(LinkStack S) //取栈顶树
{if (S != NULL) return S->Tree;else return NULL;
}
3.主函数(CountingStr.cpp)
#include <iostream>
#include <string>
#include <cmath>
#include"BiTree.h"
#include"Stack.h"
using namespace std;
bool Is_Success = true; //成功标志
int OpArrayLength = 1; //定义输入数组的长度
char StrPriority(char top, char ch) //判断符号的优先级
{if (ch == ')'&&top == '(') return '=';else if (ch == ')') return '>';else if (top == ' ' || top == '(' || ch == '(') return '<';else if (ch == '#') return '>';else if (top == '+' || top == '-'){if (ch == '+' || ch == '-') return '>';else if (ch == '/' || ch == '*') return '<';else return '0';}else if (top == '*' || top == '/') return '>';else return '0';
}void InitExpTree(char *str, LinkStack &EXPT, LinkStack &OPTR) //创建树
{//int n = strlen(str);int n = OpArrayLength; //求出有效长度BiTree T = NULL, T_left = NULL, T_right = NULL; //T,T_left和T_right分别为根结点,左孩子,右孩子char ch; //记录弹出的符号string number; //记录弹出来的数字int i = 1;while (i<n) //没扫描到最后就一直循环 &&str[i]!='#'{if (str[i] >= '0' && str[i] <= '9') {//如果它是数字,执行下列语句number += str[i]; if (str[i + 1] >= '0' && str[i + 1] <= '9') { //下一位仍是数字则连接在一起i++;continue;}CreateExpTree_Number(T, NULL, NULL, number); //创建只有一个元素的二叉树number = ""; //建完数值的二叉树后number置空Push_EXPT(EXPT, T);if(T->number!="")cout << T->number << "已出EXPT栈" << endl;i++;}else //如果它是符号,执行下列语句{switch (StrPriority(GetTop_OPTR(OPTR), str[i])) //比较优先级{case '<':Push_OPTR(OPTR, str[i]);cout << str[i] << "已入OPTR栈" << endl;i++;break;case '>':+Pop_OPTR(OPTR, ch); //弹出OPTR栈顶if(ch!=' ') cout << ch << " 已出OPTR栈!" << endl;Pop_EXPT(EXPT, T_left); //弹出两个操作数if (T_left->number != "") cout << T_left->number << " 已出EXPT栈!" << endl;Pop_EXPT(EXPT, T_right);if (T_right->number != "") cout << T_right->number << " 已出EXPT栈" << endl;CreateExpTree_Op(T, T_right, T_left, ch); //建立树Push_EXPT(EXPT, T); //最后把T放进EXPT栈中if (T->number != "") cout << T->number << " 已入EXPT栈" << endl;break;case '=':Pop_OPTR(OPTR, ch);if(ch!=' ') cout << ch << " 已出OPTR栈" << endl;i++;break;default:break;}}}
}double GetStrValue(char data, double lvalue, double rvalue) //计算表达式的值
{switch (data){case '+':return lvalue + rvalue;break;case '-':return lvalue - rvalue;break;case '*':return lvalue * rvalue;break;case '/':return lvalue / rvalue; break;default: Is_Success = false;break;}
}double ToNumber(string str) //把string字符转换成数值
{int n = str.length(), m = str.length();double sum = 0;for (int i = 0; i < n; i++){sum += (str[i] - '0') * pow(10, m - 1);m--;}return sum;
}double EvaluateExpTree(BiTree T) //遍历表达式树求表达式的值
{double lvalue = 0, rvalue = 0; //存放叶子结点的数据域if (!T->lchild&& !T->rchild)return ToNumber(T->number); //转换为数字else {lvalue = EvaluateExpTree(T->lchild); rvalue = EvaluateExpTree(T->rchild);return GetStrValue(T->opstr, lvalue, rvalue);}
}void ErrorTest(char *str1) //错误判断
{int j = 1; int left = 0, right = 0;bool wrong_flag = false;while (str1[j]!='#') //扫描有么有异常符号{ char t = str1[j];if (t != '+'&&t != '-'&&t != '*'&&t != '/'&&t != '#'&&t!='('&&t!=')'&&!(t<='9'&&t>='0')){Is_Success = false;cout << str1[j] << "符号输入错误!" << endl;wrong_flag = true;break;}j++;}j = 1; //重置为1if (!wrong_flag){while (str1[j] != '#'){if (str1[j] == '(') left++;if (str1[j] == ')') right++;if (str1[j] == ')'&&str1[j + 1] == '('){Is_Success = false;cout << str1[j] << str1[j + 1] << "处括号匹配失败!" << endl;}if ((str1[j] == '+' || str1[j] == '-' || str1[j] == '/' || str1[j] == '*') && str1[j + 1] == ')'){Is_Success = false;cout << str1[j] << str1[j + 1] << "处出现错误!" << endl;}if ((str1[j + 1] == '+' || str1[j + 1] == '-' || str1[j + 1] == '/' || str1[j + 1] == '*') && str1[j] == '('){Is_Success = false;cout << str1[j] << str1[j + 1] << "处出现错误!" << endl;}if ((str1[j] == '+' || str1[j] == '-' || str1[j] == '*' || str1[j] == '/') &&(str1[j + 1] == '+' || str1[j + 1] == '-' || str1[j + 1] == '*' || str1[j + 1] == '/')){cout << str1[j] << str1[j + 1] << "处运算符不能连续输入!" << endl;Is_Success = false;}j++;}j = 1; //重置为1if (left != right){Is_Success = false;cout << "括号数量匹配失败!" << endl;}}}void MainRun(LinkStack EXPT,LinkStack OPTR,BiTree T,char *OpArray)
{if (Is_Success){InitExpTree(OpArray, EXPT, OPTR); //构建表达式树Pop_EXPT(EXPT, T);cout << endl;int i = 1; //用于后续遍历cout << "The result of ";while (OpArray[i] != '#'){cout << OpArray[i];i++;}cout << " is: " << EvaluateExpTree(T) << endl; //求值结果}
}
int main()
{BiTree T = NULL; LinkStack EXPT; LinkStack OPTR;InitStack(EXPT);InitStack(OPTR); //char OpArray[]= "#(7+15)*(23-28/4)#";//默认char OpArray[100]; //定义表达式数组int j=1; //计数器用来循环输入cout << "请输入表达式:";cin >> OpArray[0];if (OpArray[0] != '#') { cout << "请以#开始输入!" << endl; }else{cin >> OpArray[1]; OpArrayLength++; while (OpArray[j] != '#'){cin >> OpArray[++j];OpArrayLength++;}ErrorTest(OpArray);MainRun(EXPT, OPTR, T, OpArray);}system("pause");
}
4.运行结果
7.实验总结
1.通过课程设计中不断的查找相关资料,提高了自己对陌生知识的理解和掌握。
2.课程设计中大量用到了栈,增强自己对栈的相关知识的理解和应用。
3.提高了自己对程序健壮性判断的重要性,如果没有对错误进行判断,很容易出现编译器直接报错的情况。
C++——算术表达式的求值(数据结构课程设计)相关推荐
- c语言程序设计报告表达式求值,数据结构 课程设计表达式求值 实验报告
<数据结构 课程设计表达式求值 实验报告>由会员分享,可在线阅读,更多相关<数据结构 课程设计表达式求值 实验报告(21页珍藏版)>请在人人文库网上搜索. 1.实验课程名称 级 ...
- 算术表达式字符串求值
问题: 计算字符串"10+12*13-30/20"的值 思路: 第一步:从左到右解析字符串,将数值与运算符放入数组 第二步:先计算乘除法,将求值放入队列 第三步:依次出队列,计算最 ...
- 算术表达式求值的程序设计与实现_数据结构课程设计
以下内容可且仅可供参考,如有错误欢迎指正. 部分思路借鉴算术表达式求值(C语言栈)_夜何其的博客-CSDN博客_c语言利用栈求解算术表达式侵删致歉 <算术表达式求值的程序设计与实现>题目要 ...
- 表达式求值问题数据结构课程设计
完整代码在最后~~ 1 需求分析 1.1 问题描述 表达式求值是程序设计语言编译中的一个最基本问题,就是将一个表达式转化为逆波兰表达式并求值.具体要求是以字符序列的形式从终端输入语法正确的.不含变量的 ...
- 表达式求值(数据结构栈,c语言版)
表达式求值 一.实验题目 1.案例分析 2.案例实现 3.算法步骤 4.算法描述 二.工具环境 三.实验问题 四.实验代码 一.实验题目 1.案例分析 任何一个表达式都是由操作数(operand)运算 ...
- c语言中缀表达式求值_[源码和文档分享]基于C++的表达式计算求值
一.使用说明 1.1 项目简介 表达式求值是程序设计语言编译中的一个最基本的问题,就是将一个表达式转化为逆波兰表达式并求值.具体要求是以字符序列的形式从终端输入语法正确的.不含变量的整数表达式,并利用 ...
- linux算术表达式求值数据结构,数据结构:算数表达式求值演示
题目:设计一个程序,演示用算符优先法对算数表达式求值的过程. 一.需求分析 以字符序列的形式从终端读入输入语法正确.不含变量的整数表达式.利用教科书表3.1给出的算符优先关系,实现对算数四则混合运算表 ...
- 数据结构课程设计---------用栈来实现表达式求值
1.需求分析 设计一个程序,演示用算符优先法对算术表达式求值的过程.利用算符优先关系,实现对算术四则混合运算表达式的求值. (1)输入的形式:表达式,例如2*(3+4) 包含的运算符只能有' ...
- 【数据结构】栈的应用-算术表达式求值#数据结构实验任务书
实验题目:栈的应用-算术表达式求值 正文 实验环境: Visual C++ 2010 实验目的: 1.掌握栈的定义及实现: 2.掌握利用栈求解算术表达式的方法. 实验内容: 通过修改完善教材中的算法3 ...
最新文章
- API Sanity Checker在Ubuntu中的使用
- “老赖”罗永浩:就算“卖艺”也会还债!孙宇晨:我买!
- 深度学习中张量flatten处理(flatten,reshape,reduce)
- php判断参数_php检查函数必传参数是否存在的实例详解
- php安装redis扩展'checking for igbinary includes... configure: error: Cannot find igbinary.h'解决方法...
- 如何快速生成JavaScript文档
- 让cxGrid只取一部分数据
- 《初级会计电算化应用教程(金蝶KIS专业版)》——导读
- Java开发规范文档
- 回调函数处理图像(待整理)
- 监控摄像头服务器中断是什么原因,监控系统常见问题故障及处理方法
- ios dev关闭双重认证_iOS Dev Academy简短介绍(自动布局)
- 总结1_1:常用周期函数
- 【神器】yololib 飘云修改版 -- 给iOS APP 添加导入表注入--你懂的
- 计算机xp怎么做备份,简单说说windowsXP中如何进行系统备份
- 学习笔记整理:Photoshop软件应用-图层混合与样式
- CCS5.1/5.5/6下载地址
- 新签约和新开业酒店 | 华中首家美高梅、广州奥园喜来登、苏州裸心泊度假村、南昌八一广场格雷斯精选等酒店陆续签约和开业...
- 安卓来电归属地_比尔·盖茨懊悔让微软损失4000亿美金!当年为何会与安卓失之交臂?...
- 百分百面试题:遇到过线上问题没有?