数据结构课程设计——算术表达式的求值

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++——算术表达式的求值(数据结构课程设计)相关推荐

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

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

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

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

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

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

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

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

  5. 表达式求值(数据结构栈,c语言版)

    表达式求值 一.实验题目 1.案例分析 2.案例实现 3.算法步骤 4.算法描述 二.工具环境 三.实验问题 四.实验代码 一.实验题目 1.案例分析 任何一个表达式都是由操作数(operand)运算 ...

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

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

  7. linux算术表达式求值数据结构,数据结构:算数表达式求值演示

    题目:设计一个程序,演示用算符优先法对算数表达式求值的过程. 一.需求分析 以字符序列的形式从终端读入输入语法正确.不含变量的整数表达式.利用教科书表3.1给出的算符优先关系,实现对算数四则混合运算表 ...

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

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

  9. 【数据结构】栈的应用-算术表达式求值#数据结构实验任务书

    实验题目:栈的应用-算术表达式求值 正文 实验环境: Visual C++ 2010 实验目的: 1.掌握栈的定义及实现: 2.掌握利用栈求解算术表达式的方法. 实验内容: 通过修改完善教材中的算法3 ...

最新文章

  1. API Sanity Checker在Ubuntu中的使用
  2. “老赖”罗永浩:就算“卖艺”也会还债!孙宇晨:我买!
  3. 深度学习中张量flatten处理(flatten,reshape,reduce)
  4. php判断参数_php检查函数必传参数是否存在的实例详解
  5. php安装redis扩展'checking for igbinary includes... configure: error: Cannot find igbinary.h'解决方法...
  6. 如何快速生成JavaScript文档
  7. 让cxGrid只取一部分数据
  8. 《初级会计电算化应用教程(金蝶KIS专业版)》——导读
  9. Java开发规范文档
  10. 回调函数处理图像(待整理)
  11. 监控摄像头服务器中断是什么原因,监控系统常见问题故障及处理方法
  12. ios dev关闭双重认证_iOS Dev Academy简短介绍(自动布局)
  13. 总结1_1:常用周期函数
  14. 【神器】yololib 飘云修改版 -- 给iOS APP 添加导入表注入--你懂的
  15. 计算机xp怎么做备份,简单说说windowsXP中如何进行系统备份
  16. 学习笔记整理:Photoshop软件应用-图层混合与样式
  17. CCS5.1/5.5/6下载地址
  18. 新签约和新开业酒店 | 华中首家美高梅、广州奥园喜来登、苏州裸心泊度假村、南昌八一广场格雷斯精选等酒店陆续签约和开业...
  19. 安卓来电归属地_比尔·盖茨懊悔让微软损失4000亿美金!当年为何会与安卓失之交臂?...
  20. 百分百面试题:遇到过线上问题没有?

热门文章

  1. 如何解决分布式系统数据事务一致性问题
  2. xml与java对象互转
  3. 用sass替代node-sass
  4. mysql构建数据立方体_数据立方体简介
  5. 一些下载中间件软件源地址
  6. 为什么那么多企业选择了游戏盾?
  7. codeforces 1257C Dominated Subarray
  8. OpenFace简介
  9. centos7上搭建php服务器环境
  10. keepalived+nginx/mysql双主