首页 表达式类型的实现毕业设计(论文)(已处理)

表达式类型的实现毕业设计(论文)(已处理)

举报
开通vip

表达式类型的实现毕业设计(论文)(已处理)表达式类型的实现毕业设计(论文)(已处理) 课程设计 表达式类型的实现 学 院 计算机学院 专 业 计算机科学与技术 年级班别 2006级01班 学 号 3106006394 学生姓名 方锐洲 辅导教师__ 吴伟民_______ 成 绩_______ ______ 2008年7月 3 日 表达式类型的实现 目录 一需求分析 二概要设计 1数据类型的声明 2表达式的抽象数据类型定义 3整体设计 三详细设计 1二叉树的存储类型 2顺序栈的存储类型 3表达式的基本操作 4主程序和其他伪码算...

表达式类型的实现毕业设计(论文)(已处理)
表达式类型的实现毕业 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 (论文)(已处理) 课程设计 表达式类型的实现 学 院 计算机学院 专 业 计算机科学与技术 年级班别 2006级01班 学 号 3106006394 学生姓名 方锐洲 辅导教师__ 吴伟民_______ 成 绩_______ ______ 2008年7月 3 日 表达式类型的实现 目录 一需求分析 二概要设计 1数据类型的声明 2表达式的抽象数据类型定义 3整体设计 三详细设计 1二叉树的存储类型 2顺序栈的存储类型 3表达式的基本操作 4主程序和其他伪码算法 5函数的调用关系 四设计和调试分析 五用户手册 六测试 七课程设计的心得和心得以及问题-----18 八参考文献 九附录程序清单 一需求分析课程设计要求 问题的描述 一个表达式和一棵二叉树之间存在着自然的对应关系写一个程序实现 基于二叉树表示的算术表达式Expression的操作 基本要求 一必做部分 假设算术表达式Expression内可以含有变量a-z常量0-9和二元运算 符-乘幂实现以下操作 1ReadExpr E ――以字符序列的形式输入语法正确的前缀表达式并构造 表达式E 2WriteExpr E ――用带括号的中缀表达式输出表达式E 3Assign Vc ――实现对变量V的赋值V c变量的初值为0 4Value E ――对算术表达式E求值 5CompoundExpr pE1E2 ――构造一个新的复合表达式E1pE2 二选做部分 1以表达式的原书写形式输入支持大于0的正整数常量 2增加常数合并操作MergeConst E 合并表达式E中所有常数运算例如对表 达式E 23-a b34 进行合并常数的操作后求得E 5-a b12 测试数据 分别输入0a-91abc5x28x32x2x6并输出 每当输入一个表达式后对其中的变量赋值然后对表达式求值 还有很多测试的数据详细请见附上的文件Testtxt 二概要设计 1数据类型的声明 在这个课程设计中采用了链表二叉树的存储结构以及两个顺序栈的辅助 存储结构 头文件以及存储结构 include include include include define TRUE 1 define FALSE 0 define OK 1 define ERROR 0 define OVERFLOW 0 typedef int Status 2表达式的抽象数据类型定义 ADT Expression 数据对象DD是具有数值的常量C和没有数值的变量V 数据关系R V或者C P V或者C VC?D V或者C P V或者C 表示由运算符P结合起来的表达式E 基本操作 Status Input_Expr stringflag 操作结果以字符序列的形式输入语法正确的前缀表达式保存到字符串string 参数flag表示输出的提示信息是什么输入成功返回OK否则返回ERROR void judge_value Estringi 初始条件树E存在表达式的前缀字符串string存在 操作结果判断字符string[i]如果是0-9常量之间二叉树结点E存为整型否则存为字符型 Status ReadExpr Eexprstring 初始条件表达式的前缀形式字符串exprstring存在 操作结果以正确的前缀表示式exprstring并构造表达式E构造成功返回OK否则返回ERROR Status Pri_Compare c1c2 初始条件c1和c2是字符 操作结果如果两个字符是运算符比较两个运算符的优先级c1比c2优先返回OK否则返回ERROR void WriteExpr E 初始条件表达式E存在 操作条件用带括弧的中缀表达式输入表达式E void Assign EVcflag 初始条件表达式E存在flag为标志是否有赋值过 操作结果实现对表达式E中的所有变量V的赋值 V c long Operate opr1opropr2 初始条件操作数opr1和操作数opr2以及操作运算符opr 操作结果运算符运算求值参数opr1opr2为常量opr为运算符根据不同的运 算符实现不同的运算返回运算结果 Status Check E 初始条件表达式E存在 操作结果检查表达式E是否还存在没有赋值的变量以便求算数表达式E的值 long Value E 初始条件表达式E存在 操作结果对算术表达式求值返回求到的结果 void CompoundExpr PE1E2 初始条件表达式E1和E2存在 操作条件构造一个新的复合表达式 E1 P E2 Status Read_Inorder_Expr stringpre_expr 操作结果以表达式的原书写形式输入表达式的原书写形式字符串string变 为字符串pre_expr后调用reversal_string 函数反转得到前缀表达式 pre_expr得到正确的前缀表达式返回OK否则返回ERROR void MergeConst E 操作结果常数合并操作合并表达式E中所有常数运算 ADT Expression 3整体设计 在这个课程设计中有两个源代码文件expressionh和expressionc 在expressionh文件中包含了各个存储结构的声明和辅助存储结构的两个栈的基本操作在expressionc文件中是实现课程设计要求的各个函数 《一》expressionh文件的整体结构 1各个存储结构的声明 2两个除了栈名和栈存储的元素不一样的顺序栈的基本操作其基本操作如下 对于栈SqStack Status InitStack SqStack S 构造一个空栈S Status StackEmpty SqStack S 若栈S为空栈则返回TRUE否则返回FALSE Status Push SqStack SSElemType e 插入元素e为新的栈顶元素 Status Pop SqStack SSElemType e 若栈不空则删除S的栈顶元素用e返回其值并返回OK否则返回ERROR Status GetTop SqStack SSElemType e 若栈不空则用e返回S的栈顶元素并返回OK否则返回ERROR 对于栈SqStack1 Status InitStack1 SqStack1 S 构造一个空栈S Status StackEmpty1 SqStack1 S 若栈S为空栈则返回TRUE否则返回FALSE Status Push1 SqStack1 SSElemType1 e 插入元素e为新的栈顶元素 Status Pop1 SqStack1 SSElemType1 e 若栈不空则删除S的栈顶元素用e返回其值并返回OK否则返回ERROR Status GetTop1 SqStack1 SSElemType1 e 若栈不空则用e返回S的栈顶元素并返回OK否则返回ERROR 顺序栈的基本操作的算法见程序清单 《二》expressionc文件的整体结构 1主程序模块的整体流程 可以从主菜单函数可以明了的了解的程序的整体流程主菜单函数menu 如下 char menu char choice printf "\n" printf "\n 1 输入正确的前缀表达式" printf "\n 2 带括弧的中缀表示式输出" printf "\n 3 对变量进行赋值" printf "\n 4 对算数表达式求值" printf "\n 5 构造一个新的复合表达式" printf "\n 6 以表达式的原书写形式输入" printf "\n 7 合并表达式中所有常数运算" printf "\n 0 退出" printf "\n" printf "\n请输入你的选择 " choice getche return choice 在主函数中采用多分支程序设计语句switch 使程序产生不同的流向从而 达到实现课程设计的各个要求 void main while 1 清屏 switch 主菜单 根据不同的选择调用不同的操作函数完成各个操作 2本程序有四个模块主程序模块二叉树模块两个顺序栈模块四者的调用关 系如下 主程序模块中的对于表达式的存储结构调用了二叉树模块而在构造表达式的二叉树模块中又调用了顺序栈SqStack模块主程序中在将原表达式形式输入表达式转换为前缀表达式操作中调用了顺序栈SqStack1模块 三详细设计 1二叉树的存储类型 二叉树结点类型 typedef enum INTCHAR ElemTagINT为整型数据numCHAR为字符型数据c typedef struct TElemType ElemTag tag INTCHAR 指示是整型还是字符型 union int numtag INT时为整型 char ctag CHAR时为字符型 TElemType 二叉树的二叉链表存储表示 typedef struct BiTNode TElemType data struct BiTNode lchildrchild 左右孩子指针 BiTNodeBiTree 二叉树的基本操作已经在构造表达式和表达式中的基本操作中根据不同的 功能和实际情况修改了详细见各个函数操作的算法设计 2顺序栈的存储类型 栈的顺序存储表示 define STACK_INIT_SIZE 10 存储空间初始分配量 define STACKINCREMENT 2 存储空间分配增量 两个顺序栈 typedef struct SqStack SElemType base 在栈构造之前和销毁之后base的值为NULL SElemType top 栈顶指针 int stacksize 当前已分配的存储空间以元素为单位 SqStack 顺序栈SqStack typedef struct SqStack1 SElemType1 base 在栈构造之前和销毁之后base的值为NULL SElemType1 top 栈顶指针 int stacksize 当前已分配的存储空间以元素为单位 SqStack1 顺序栈SqStack1 相关的基本操作见上面的expressionh文件的整体结构的说明详细的算法 设计见附录的程序清单 3表达式的基本操作 Status Input_Expr char stringint flag 以字符序列的形式输入语法正确的前缀表达式保存到字符串string 参数flag 0表示输出的提示信息是"请输入正确的前缀表示式" flag 1表示输出的提示信息为"请以表达式的原书写形式输入正确表示式" void judge_value BiTree Echar stringint i 判断字符string[i]如果是0-9常量之间二叉树结点存为整型否则存为字符型 Status ReadExpr BiTree Echar exprstring 以正确的前缀表示式并构造表达式E Status Pri_Compare char c1char c2 如果两个字符是运算符比较两个运算符的优先级c1比c2优先返回OK否则返回ERROR void WriteExpr BiTree E 用带括弧的中缀表达式输入表达式 void Assign BiTree Echar Vint cint flag 实现对表达式中的所有变量V的赋值 V c 参数flag为表示是否赋值过的标志 long Operate int opr1char oprint opr2 运算符运算求值参数opr1opr2为常量opr为运算符根据不同的运算符实现不同的运算返回运算结果 Status Check BiTree E 检查表达式是否还存在没有赋值的变量以便求算数表达式的值 long Value BiTree E 对算术表达式求值 void CompoundExpr char PBiTree E1BiTree E2 构造一个新的复合表达式 Status Read_Inorder_Expr char stringchar pre_expr 以表达式的原书写形式输入表达式的原书写形式字符串string变为字符串 pre_expr后调用reversal_string 函数反转得到前缀表达式pre_expr void MergeConst BiTree E 常数合并操作函数合并表达式E中所有常数运算 下面列出部分基本操作的伪码算法未列出的请见程序清单 其中部分基本操作的伪码算法如下 4主程序和其他伪码算法 void main while 1 switch menu case 1输入正确的前缀表达式 if Input_Expr Expr_String0 输入正确的前缀表达式 if ReadExpr EExpr_String 构造表达式 flag 1printf "\n表达式构造成功" case 2带括弧的中缀表示式输出 if flag 1 WriteExpr E else printf "\n表达式未构造成功请构造成功的表达式" case 3对变量进行赋值 if flag 1 flushall 清理缓冲区 V getchar scanf c Assign EVcAssign_flag else printf "\n表达式未构造成功请构造成功的表达 式" case 4对算数表达式求值 if flag 1 if Check E result Value E WriteExpr E printf result else printf "\n表达式未构造成功请构造成功的表达 式" case 5构造一个新的复合表达式 if flag 1 flushall 清理缓冲区 if Input_Expr string1 if Read_Inorder_Expr stringExpr_String 按原表达式形式输入 reversal_string Expr_String if ReadExpr E1Expr_String flag 1P getchar CompoundExpr PEE1 else printf "\n复合新的表达式失败请按 任意键返回主菜单" case 6以表达式的原书写形式输入 if Input_Expr string1 if Read_Inorder_Expr stringExpr_String reversal_string Expr_String if ReadExpr EExpr_String flag 1printf "\n表达式构造成功" case 7合并表达式中所有常数运算 if flag 1 MergeConst E case 0退出 5函数的调用关系 除了主函数main 外其他各个函数相对于其它函数来说是独立的函数的使用都由主函数main 调用使用的可以简单的说各个函数都是主函数下的从函数 四设计和调试分析 1在起初设计上针对前缀表达式的要求构造表达式E常量的范围限定在0-9之间后在这个构造表达式的架构上逐个逐个实现对表达式上的操作后扩展到以表达式的原书写形式输入整体架构是不变的只是增加一些细节的处理功能这样的设计从开始到最后都处于可扩展的模块化设计 2在算法设计中构造表达式树的时候本来以为使用递归构造表达式会很难做到出错处理的所以采用了顺序栈辅助构造方法并且尽可能地对程序进行完善出错处理但是经过与同学的相互讨论和研究发现自己的想法犯了很大的错误递 归构造表达式对于出错处理很简单也很完善这一点让我加深了递归的使用和理解 3在对各个功能操作的实现上时间复杂度大多数是O n 空间上增加了辅助栈空间复杂度为O ns 而在以原表达式形式输入操作上实际上是对字符串的操作将一串原表达式字符串处理为前缀表达式字符串而已算法时间复杂度取决于输入的字符串的长度n即O n 空间复杂度为O 2ns 整体的算法设计没有什么可取之处对于减少时间复杂度和空间复杂度上没有什么细细考虑 4在调试的过程中花费时间最为多的是对输入错误表达式的出错处理更改增加的代码几乎都是为了出错处理但是觉得这样的调试才更能锻炼一个人的编程能力课程设计注重的不单单只是基本程序的完成更多注重的是出错处理和界面的美化 五用户手册 1本程序的运行环境为DOS操作系统执行文件为expressionexe 2进入演示程序后首先出现一个主菜单主菜单界面如下 3之后输入你的选择进入你所要进行的操作中 六测试 《一》选择1进入测试输入正确的前缀表达式操作 1输入的前缀表达式为一个不大于9常量8 2输入前缀表达式为一个变量Z 3输入前缀表达式为一个简单的运算表达式-91 4输入前缀表达式为一个较为复杂的带有变量的表达式3x32x2x6 5输入前缀表达式-23ab34输出带括弧的表达式 6输入错误的前缀表达式999和5x28x 《二》选择3进入测试对变量的赋值 1对前缀表达式3x32x2x6中变量x进行赋值赋值为5 2对前缀表达式abc中的变量b进行赋值赋值为6 3对前缀表达式5x28x中不存在的变量y进行赋值赋值为4 《三》选择4进入测试求算数表达式的值 1求算数表达式98的值 2求算数表达式659892 21-96 输出的结果少了括弧这个是程序中的一个BUG程序的判定带括弧输出表达 式时判断两个优先级别时的一个很大的BUG一个本人自己没法解决的BUG 2构造表达式 32 9 - 63 91 8183 输出的结果简化了多余的括弧这一点是一个很大的优化 3构造表达式66出错处理 4构造表达式6-b99出错处理 5构造表达式9a 65 a出错处理多余输入的括弧 6构造表达式6986出错处理输入非运算符和非变量常量的表达式 《六》选择7进入合并常数操作 1构造表达式 23-a b34 后合并常数操作 2构造表达式334经过多次合并得出最后结果 这个合并常数操作唯一的缺点就是要多次操作但是这个缺点也不能说为缺 点它可以很清晰的反映出表达式求值的步骤 经过对各个操作的测试可以这样总结的说基本完成了课程设计的要求虽说 其中有一些操作还存在BUG需要去完善改进 七课程设计的心得和体会以及问题 此次课程设计相对于我来说难度适中相对于这个学期写的那些小算法来说这个课程设计能充分发挥出学习数据结构后的能力而相对于之前做的设计性实验又有了实际的应用现实应用度增加 从接触C语言编程到现在我就觉得编程不是简简单单的写出程序更多的是出错处理和界面设计这次课程设计中更让我深刻体会到这个道理编出大体的程序架构花费了我的时间不多而花费了我很多时间的是在调试和测试数据上这次课程设计不仅训练了我对Visual C60的调试器的操作的熟练度而且让我在发现问题解决问题中深刻地理解到完善程序的重要性 这次课程设计在技术上的学习上我觉得让我更懂得递归递归的使用更加熟练递归的分析更加清晰递归的思想更加深化 做课程设计我觉得第一点是架构一个好的架构可以让细节更完善在这次课程设计中我首先确定的是一个架构前缀表达式构造表达式为架构其余的操作都是在这个架构上增加扩充第二点是调试测试分析一个完善的程序是要经过千锤百炼的也能做到更加完善第三点是心得的总结 总的来说这次课程设计让我学了很多总结了很多 八参考文献 严蔚敏吴伟民著数据结构C语言版北京清华大学出版社2007 谭浩强著C程序设计第三版北京清华大学出版社2005 九附录程序清单 源程序文件名清单 expressionh 包含头文件存储结构的声明以及两个顺序栈的基本操作 exprssionc 包含主程序和表达式的基本操作 《一》文件expressionh 头文件以及存储结构 include include include include define TRUE 1 define FALSE 0 define OK 1 define ERROR 0 define OVERFLOW 0 typedef int Status 二叉树结点类型 typedef enum INTCHAR ElemTagINT为整型数据numCHAR为字符型数据c typedef struct TElemType ElemTag tag INTCHAR 指示是整型还是字符型 union int numtag INT时为整型 char ctag CHAR时为字符型 TElemType 二叉树的二叉链表存储表示 typedef struct BiTNode TElemType data struct BiTNode lchildrchild 左右孩子指针 BiTNodeBiTree typedef BiTree SElemType栈SqStack的元素 typedef char SElemType1 栈SqStack1的元素 栈的顺序存储表示 define STACK_INIT_SIZE 10 存储空间初始分配量 define STACKINCREMENT 2 存储空间分配增量 两个顺序栈 typedef struct SqStack SElemType base 在栈构造之前和销毁之后base的值为NULL SElemType top 栈顶指针 int stacksize 当前已分配的存储空间以元素为单位 SqStack 顺序栈 typedef struct SqStack1 SElemType1 base 在栈构造之前和销毁之后base的值为NULL SElemType1 top 栈顶指针 int stacksize 当前已分配的存储空间以元素为单位 SqStack1 顺序栈 顺序栈的基本操作 Status InitStack SqStack S 构造一个空栈S S base SElemType malloc STACK_INIT_SIZEsizeof SElemType if S base exit OVERFLOW 存储分配失败 S top S base S stacksize STACK_INIT_SIZE return OK Status StackEmpty SqStack S 若栈S为空栈则返回TRUE否则返回FALSE if Stop Sbase return TRUE else return FALSE Status Push SqStack SSElemType e 插入元素e为新的栈顶元素 if S top- S base S stacksize 栈满追加存储空间 S base SElemType realloc S base S stacksizeSTACKINCREMENT sizeof SElemType if S base exit OVERFLOW 存储分配失败 S top S base S stacksize S stacksize STACKINCREMENT S top e return OK Status Pop SqStack SSElemType e 若栈不空则删除S的栈顶元素用e返回其值并返回OK否则返回ERROR if S top S base return ERROR e -- S top return OK Status GetTop SqStack SSElemType e 若栈不空则用e返回S的栈顶元素并返回OK否则返回ERROR if Stop Sbase e Stop-1 return OK else return ERROR 顺序栈的基本操作 Status InitStack1 SqStack1 S 构造一个空栈S S base SElemType1 malloc STACK_INIT_SIZEsizeof SElemType1 if S base exit OVERFLOW 存储分配失败 S top S base S stacksize STACK_INIT_SIZE return OK Status StackEmpty1 SqStack1 S 若栈S为空栈则返回TRUE否则返回FALSE if Stop Sbase return TRUE else return FALSE Status Push1 SqStack1 SSElemType1 e 插入元素e为新的栈顶元素 if S top- S base S stacksize 栈满追加存储空间 S base SElemType1 realloc S base S stacksizeSTACKINCREMENT sizeof SElemType1 if S base exit OVERFLOW 存储分配失败 S top S base S stacksize S stacksize STACKINCREMENT S top e return OK Status Pop1 SqStack1 SSElemType1 e 若栈不空则删除S的栈顶元素用e返回其值并返回OK否则返回ERROR if S top S base return ERROR e -- S top return OK Status GetTop1 SqStack1 SSElemType1 e 若栈不空则用e返回S的栈顶元素并返回OK否则返回ERROR if Stop Sbase e Stop-1 return OK else return ERROR 《二》文件expressionc include"expressionh" 全局变量 int save_number[31]在按原表达式输入形式中输入的常量保存到数组 save_number中常量最多为30个0单元不用 char Expr_String[30]存放表达式的字符串 以字符序列的形式输入语法正确的前缀表达式保存到字符串string 参数flag 0表示输出的提示信息是"请输入正确的前缀表示式" flag 1表示输出的提示信息为"请以表达式的原书写形式输入正确表示 式" Status Input_Expr char stringint flag if flag 0 printf "\n请输入正确的前缀表示式" else printf "\n请以表达式的原书写形式输入正确表示式" flushall 清理缓冲区 gets string 从键盘输入一串字符串作为表达式 if strlen string 1 输入的表达式字符串长度为1 if string[0] string[0] -string[0] string[0] string[0] 输入的表达式只有一个运算符 printf "\n表达式只有一个字符为运算符错误" return ERROR else if string[0] 0string[0] 9 string[0] astring[0] z string[0] Astring[0] Z 输入的表达式只有一个数字或字符 printf "\n表达式只有一个字符" return OK else printf "\n输入的字符不是运算符也不是变量常量错误" return ERROR return OK 判断字符string[i]如果是0-9常量之间二叉树结点存为整型否则存为 字符型 void judge_value BiTree Echar stringint i if string[i] 0string[i] 9 为常量 E - datatag INT E - datanum string[i]-48 else if string[i] 1string[i] 20 为常量常量存于数组 save_number中 E - datatag INT E - datanum save_number[string[i]] else为变量 E - datatag CHAR E - datac string[i] 以正确的前缀表示式并构造表达式E Status ReadExpr BiTree Echar exprstring SqStack S int ilenlen为表达式的长度 BiTree pq E BiTree malloc sizeof BiTNode 申请二叉树的根结点的空间 E - lchild NULL E - rchild NULL len strlen exprstring len赋值为表达式的长度 if len 1 表达式长度为1时二叉树只有根结点 judge_value Eexprstring0 将exprstring[0]存入二叉树的结 点中 else judge_value Eexprstring0 将exprstring[0]存入二叉树的结 点中 InitStack S 初始化栈 q E Push Sq 入栈 Push Sq 入栈根结点入栈两次是为判断先序输入的表达式是不是正确的表达式 for i 1i lenStackEmpty S i p BiTree malloc sizeof BiTNode judge_value pexprstringi 将exprstring[i]存入二叉树的结点中 p- lchild NULL p- rchild NULL if exprstring[i] exprstring[i] -exprstring[i] exprstring[i] exprstring[i] 为运算符运算符入栈左孩子不空向左孩子走否则如果右孩子不空向右孩子走 if q- lchild q- lchild pPush Sp q p else q- rchild pPush Sp q p else不是运算符运算符出栈 if q- lchild q- lchild pPop Sq else q- rchild pPop Sq if StackEmpty S i len return OK栈空且i len说明输入的表达式是正确的 else 输入的表达式是错误的 printf "\n输入的表达式有误" return ERROR 如果两个字符是运算符比较两个运算符的优先级c1比c2优先返回OK否则返回ERROR Status Pri_Compare char c1char c2 if c1 c1 c1 -c1 c1 c2 c2 c2 -c2 c2 c1和c2为运算符 if c1 c1为指数运算符则当c2不为时c1比c2优先 if c2 return OK else return ERROR else if c1 c1 c1为乘法或除法运算符则当c2为或-c1比c2优先 if c2 c2 c2 return ERROR else return OK else return ERROR其余c1不比c2优先 else return ERRORc1和c2不是运算符 用带括弧的中缀表达式输入表达式 void WriteExpr BiTree E if E 树不为空 先递归左子树 if E- lchildE- lchild- datatag CHAR E的左孩子不为空且左孩子为字符 if Pri_Compare E- datacE- lchild- datac E- datac比E- lchild- datac优先 printf " " WriteExpr E- lchild printf " " 带括弧输出左子树 else WriteExpr E- lchild 否则不带括弧输出左子树 else WriteExpr E- lchild 否则输出左子树 访问输出根结点的值 if E- datatag INT printf "d"E- datanum else printf "c"E- datac 后递归右子树 if E- rchildE- rchild- datatag CHAR E的右孩子不为空且右孩子为字符 if Pri_Compare E- datacE- rchild- datac E- datac比E- rchild- datac优先 printf " " WriteExpr E- rchild printf " " 带括弧输出右子树 else WriteExpr E- rchild 否则不带括弧输出右子树 else WriteExpr E- rchild 否则输出右子树 实现对表达式中的所有变量V的赋值 V c 参数flag为表示是否赋值过的标志 void Assign BiTree Echar Vint cint flag if E if E - datatag CHAR E - datac V 如果找到要赋值的变量 赋值 E - datatag INT E - datanum cflag 1 Assign E - lchild Vcflag 递归左子树 Assign E - rchild Vcflag 递归左子树 指数运算函数底数为x指数为exp long power int xint exp long result int i for i 1result 1i expi result x return result 运算符运算求值参数opr1opr2为常量opr为运算符根据不同的运算符实 现不同的运算返回运算结果 long Operate int opr1char oprint opr2 long result switch opr case 加法 result opr1opr2 return resultbreak case -减法 result opr1-opr2 return resultbreak case 乘法 result opr1opr2 return resultbreak case 除法除法是在整型类型上的除法 result opr1opr2 return resultbreak case 指数运算 result power opr1opr2 return resultbreak defaultbreak 检查表达式是否还存在没有赋值的变量以便求算数表达式的值 Status Check BiTree E if EE- datatag CHAR 树不为空 if E- datac E- datac E- datac -E- datac E- datac printf "\n表达式中仍存在变量没有赋值没法求出表达式 的值" return ERROR 存在变量提示信息后返回ERROR if Check E- lchild 递归左子树 Check E- rchild 递归右子树 对算术表达式求值 long Value BiTree E if E 树不为空 if E- lchildE- rchildE- datatag INT return E- datanum 结点的左孩子和右孩子为空为叶子结点返回结点的值 return Operate Value E- lchild E- datacValue E- rchild 运算求值后根遍历的次序对表达式求值其中参数递归调用了 Value 函数求左子树的值和右子树的值 构造一个新的复合表达式 void CompoundExpr char PBiTree E1BiTree E2 BiTree E E BiTree malloc sizeof BiTNode 申请一个结点存放运算符P E- datatag CHAR E- datac P申请到的结点值为P E- lchild E1 结点的左孩子为E1 E- rchild E2结点的右孩子为E2 E1 E E1 为根结点 printf "\n表达式E复合成功其表达式变为\n" WriteExpr E 输出复合好的表达式 以表达式的原书写形式输入表达式的原书写形式字符串string变为字 符串pre_expr 后调用reversal_string 函数反转得到前缀表达式pre_expr Status Read_Inorder_Expr char stringchar pre_expr int ijlenchar_number 1len表示字符串string的长度char_number 是 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 数组save_number[]的个数 int number保存大于9的常量 char cc1 SqStack1 S栈定义 InitStack1 S 初始栈 Push1 S 先将字符入栈用来表示作为栈的最底一个元素 len strlen string len为字符串string的长度 c string[len-1]从字符串的最后一个字符开始向前扫描 i len-1 while StackEmpty1 S i 0 栈不为空且i大于等于0 if c 字符为 Pop1 Sc 出栈赋值给c while c 假如c不为 出栈 pre_expr c if StackEmpty1 S GetTop1 Sc1 c1 Pop1 Sc else printf "\n输入的表达式有误" return ERROR else if c 字符为 入栈 Push1 Sc else if c 0c 9 字符为0-9之间循环扫描string前一个字符后确定常量的大小 number c-48number为第一个常量字符的ASCII码-48 for c1 string[i-1]j 1 c1 0c1 9 i 0ji-- 循环扫描string前一个字符求出常量后 赋给number number c1-48 power 10j numbernumber为扫描到的常量 c1 string[i-2] save_number[char_number] number将number存入到数组save_number中下标为 char_number pre_expr char_number else if c ac z c Ac Z 字符为a-z或A-Z之间的变量 string下一个字符不能为常量或变量否则出错 if string[i-1] 0string[i-1] 9 string[i-1] Astring[i-1] Z string[i-1] astring[i-1] z printf "\n输入的表达式有误" return ERROR else pre_expr c else if c c 字符为运算符或 while GetTop1 Sc1 c1 将c与栈顶的字符c1比较优先 级 Pop1 Sc1 pre_expr c1 如果c1比c优先出栈 Push1 Sc 入栈字符c else if c c - 字符为运算符或- while GetTop1 Sc1 c1 c1 c1 将c与栈顶的字符c1 比较优先级 Pop1 Sc1 pre_expr c1 如果c1比c优先出栈 Push1 Sc 入栈运算符c else if c 字符为运算符 Push1 Sc 入栈运算符 else printf "\n输入的表达式有误" return ERROR 其他字符 错误返回ERROR i--下一个字符 if i 0 c string[i]i不小于0c string[i]循环下一个字符 else 否则将清空栈 while StackEmpty1 S GetTop1 Sc1 c1 Pop1 Sc pre_expr c Pop1 Sc 将出栈 pre_expr \0字符串结束符 if i 0StackEmpty1 S return OK else return ERROR 将字符串exprstring反转过来 void reversal_string char exprstring int lenij char temp len strlen exprstring len为exprstring的长度 for i 0j len-1i jij-- 字符串前后两个字符对换 temp exprstring[i] exprstring[i] exprstring[j] exprstring[j] temp 常数合并操作函数合并表达式E中所有常数运算 void MergeConst BiTree E long result if E - lchild E - rchild 左右孩子不为空 if E - lchild- datatag INT E - rchild- datatag INT 假如左右孩子为常量合并 result Operate E - lchild- datanum E - datac E - rchild- datanum 常数合并运算调用 Operate 函数求值 E - datatag INT E - datanum result修改之前的运算符为常量 free E - lchild 释放左孩子 free E - rchild 释放右孩子 E - lchild E - rchild NULL左右孩子置空 else MergeConst E - lchild 递归左孩子 MergeConst E - rchild 递归右孩子 主菜单 char menu char choice printf "\n\t" printf "\n\t 计算机学院 计算机科学与技术06级01班" printf "\n\t 学号3106006394 姓名方锐洲" printf "\n\t" printf "\n\t表达式类型的实现" printf "\n\t 1 输入正确的前缀表达式" printf "\n\t 2 带括弧的中缀表示式输出" printf "\n\t 3 对变量进行赋值" printf "\n\t 4 对算数表达式求值" printf "\n\t 5 构造一个新的复合表达式" printf "\n\t 6 以表达式的原书写形式输入" printf "\n\t 7 合并表达式中所有常数运算" printf "\n\t 0 退出" printf "\n\t" printf "\n\t请输入你的选择 " choice getche return choice 主函数 void main BiTree EE1两个表达式E和E1 int flag 0表达式E构造标志为0表示未构造为1表示已构造 long result保存算数表达式运算结果 char VP int c char string[30] while 1 system "cls" switch menu case 11 输入正确的前缀表达式 printf "\n\t输入提示信息" printf "\n\t输入正确的前缀表达式的要求" printf "\n\t\t变量 a-z或A-Z" printf "\n\t\t常量 0-9不能超过9" printf "\n\t\t运算符 - 乘幂 " printf "\n\t请输入正确的前缀表达式后按回车键存入缓冲区否则可能会出错" printf "\n\t" if Input_Expr Expr_String0 if ReadExpr EExpr_String flag 1printf "\n表达式构造成功\n输入的带括弧的中缀表达式" WriteExpr E getch break case 22 带括弧的中缀表示式输出 printf "\n\t输出说明信息" printf "\n\t输出带括弧的中缀表达式" printf "\n\t1如果表达式已经构造成功的输出表达式" printf "\n\t2如果表达式还未构造成功的请返回主菜单选择构造表达式" printf "\n\t注其中要注意的是可能有一些表达式构造时没有办法判断为有误" printf "\n\t 如果输出不是你想得到的说明你之前输入的表达式有误请重新构造" printf "\n\t" if flag 1 printf "\n带括弧的中缀表达式为" WriteExpr E else printf "\n表达式未构造成功请构造成功的表达式" getch break case 33 对变量进行赋值 printf "\n\t赋值操作说明信息" printf "\n\t赋值操作实现对表达式中的某一个变量V的赋值即使V CC为一整数" printf "\n\t 1根据输出的表达式输入要赋值的变量V只能输入一个字符否则出错" printf "\n\t 2输入要将变量V赋值为的整数C只能是整数否则出错" printf "\n\t 注如果表达式未构造请回到主菜单选择构造表达式" printf "\n\t" if flag 1 int Assign_flag 0 printf "\n表达式E为" WriteExpr E flushall 清理缓冲区 printf "\n请输入要赋值的值" V getchar printf "请输入要将赋值为" scanf "d"c Assign EVcAssign_flag if Assign_flag printf "\n赋值成功\n赋值后的表达式为" WriteExpr E else printf "\n表达式里没有c这个变量"V else printf "\n表达式未构造成功请构造成功的表达式" getch break case 44 对算数表达式求值 printf "\n\t算数表达式求值说明信息" printf "\n\t 注如果表达式还有变量未赋值即表达式不是算数表达式" printf "\n\t 不能求出表达式的值请回到主菜单选择赋值操作后再求值" printf "\n\t" if flag 1 printf "\n算数表达式" WriteExpr E if Check E result Value E printf "\n求算数表达式的值\t" WriteExpr E printf " ld"result else printf "\n表达式未构造成功请构造成功的表达式" getch break case 55 构造一个新的复合表达式 printf "\n\t构造新的复合表达式说明信息" printf "\n\t 1构造一个新的表达式E1采用表达式的原书写形式输入" printf "\n\t 2构造表达式E1成功后输入要复合表达式E和E1的操作运算符 - " printf "\n\t 注如表达式E未构造不能复合表达式如构造表达式E1错误复合失败" printf "\n\t" if flag 1 printf "\n表达式E1为" WriteExpr E printf "\n请构造新的表达式E2" flushall 清理缓冲区 if Input_Expr string1 if Read_Inorder_Expr stringExpr_String reversal_string Expr_String if ReadExpr E1Expr_String flag 1printf "\n表达式E1构造成功" WriteExpr E1 printf "\n请输入要构造新的复合表达式的操作运算符 " P getchar while P P P P -P flushall 清理缓冲区 printf "\n输入的操作运算符有误请重新输入 " P getchar CompoundExpr PEE1 else printf "\n复合新的表达式失败请按任意键返回主菜单" else printf "\n表达式未构造成功请构造成功的表达式" getch break case 66 以表达式的原书写形式输入 printf "\n\t以表达式的原书写形式输入说明信息" printf "\n\t输入正确的原书写形式表达式" printf "\n\t 变量 a-z或A-Z" printf "\n\t 常量 大于等于0的正整数" printf "\n\t 运算符 - 乘幂 " printf "\n\t 括弧 左括弧 右括弧 " printf "\n\t 注 表示式中常量最多只能是30个超过30个出错" printf "\n\t按原书写形式输入中请按照正确的方式输入否则可能会出错" printf "\n\t" if Input_Expr string1 if Read_Inorder_Expr stringExpr_String reversal_string Expr_String if ReadExpr EExpr_String flag 1printf "\n表达式构造成功\n输入的带括弧的中缀表达式" WriteExpr E getch break case 77 合并表达式中所有常数运算 printf "\n合并表达式中的所有常数运算" printf "\n 注合并表达式中的所有常数运算并不能一次性将常数都合并" printf "\n例如表达式12 33493 的常数合并选择7进行合并结果变为\n12 3123 " printf "根据优先级先后合并的如果要合并到最后需多次选择7\n进行合并又合并一次12 153 " printf "再次合并1218再次合并136\n再次合并37后无法合并" printf "\n" if flag 1 printf "\n原表达式为" WriteExpr E MergeConst E printf "\n合并表达式中所有的常数运算后的表达 式" WriteExpr E else printf "\n表达式未构造成功请构造成功的表达 式" getch break case 00 退出 printf "\n请按任意键退出" getch exit 0 default printf "\n输入有误请按任意键回到主菜单重新选择" getch break 数据结构课程设计报告 第 2 页 共 35 页 主程序模块 二叉树模块 顺序栈SqStack模块 顺序栈SqStack1模块 Status ReadExpr BiTree Echar exprstring 以正确的前缀表示式并构造表达式E 申请根结点空间 E BiTree malloc sizeof BiTNode 并且左右孩子指 针置空 表达式只有一个字符二叉树只有根结点 否则 judge_value Eexprstring0 将exprstring[0]存入二叉树的结点中 InitStack S 初始化栈 Push Sq Push Sq 入栈根结点入栈两次是为判断先序输入的表达式是不是正确的表达式 for i 1i lenStackEmpty S i 申请根结点空间p BiTree malloc sizeof BiTNode 并且左右孩子指针置空 if exprstring[i]为运算符 运算符入栈左孩子不空向左孩子走否则如果右孩子不空向右孩子走 else 不是运算符运算符出栈 根据StackEmpty S i len判断输入的表达式是正确的 正确返回OK错误返回ERROR void WriteExpr BiTree E 用带括弧的中缀表达式输入表达式 if E 树不为空 先递归左子树 WriteExpr E- lchild 其中要考虑何时带括弧输出 if Pri_Compare E- datacE- lchild- datac E- datac比E- lchild- datac优先带括弧输出左子树 访问输出根结点的值 后递归右子树 WriteExpr E- lchild 其中要考虑何时带括弧输出 if Pri_Compare E- datacE- lchild- datac E- datac比E- lchild- datac优先带括弧输出右子树 void Assign BiTree Echar Vint cint flag 实现对表达式中的所有变量V的赋值 V c 参数flag为表示是否赋值过的 标志 if E 树不空 if E - datatag CHAR E - datac V 如果找到要赋值的变量赋值flag 1 Assign E - lchild Vcflag 递归左子树 Assign E - rchild Vcflag 递归左子树 long Operate int opr1char oprint opr2 运算符运算求值参数opr1opr2为常量opr为运算符根据不同的运算符实现 不同的运算返回运算结果 switch opr 根据不同的运算符进入不同分支求出result 后返回result Status Check BiTree E 检查表达式是否还存在没有赋值的变量以便求算数表达式的值 if EE- datatag CHAR 树不为空 如果找到没有赋值的变量返回ERROR if Check E- lchild 递归左子树 Check E- rchild 递归右子树 long Value BiTree E 对算术表达式求值 if E 树不为空 如果是叶子结点返回叶子的结点的值 return Operate Value E- lchild E- datacValue E- rchild 后根遍 历的次序对表达式求值 void CompoundExpr char PBiTree E1BiTree E2 构造一个新的复合表达式 E BiTree malloc sizeof BiTNode 申请一个结点存放运算符P E- lchild E1 结点的左孩子为E1 E- rchild E2结点的右孩子为E2 E1 E E1 为根结点 Status Read_Inorder_Expr char stringchar pre_expr 以表达式的原书写形式输入表达式的原书写形式字符串string变为字符 串pre_expr后调用reversal_string 函数反转得到前缀表达式pre_expr InitStack1 S 初始栈 c string[len-1]从字符串的最后一个字符开始向前扫描 len strlen string while StackEmpty1 S i 0 栈不为空且i大于等于0 if c 字符为 Pop1 Sc while c 假如c不为 出栈 else if c 字符为 入栈 Push1 Sc else if c 0c 9 字符为0-9之间循环扫描string前一个字符后确定常量的大小 else if c ac z c Ac Z 字符为a-z或A-Z之间的变量 else if c c 字符为运算符或 比较优先级后确定是入栈还是出栈 else if c c - 字符为运算符或- 比较优先级后确定是入栈还是出栈 else if c 字符为运算符 优先级最大不用比较直接入栈 else printf "\n输入的表达式有误" return ERROR 其他字符错误返回ERROR 下一个字符继续循环 pre_expr \0字符串结束符 判断构造是否成功成功返回OK否则返回ERROR void MergeConst BiTree E 常数合并操作函数合并表达式E中所有常数运算 if E - lchild E - rchild 左右孩子不为空 if E - lchild- datatag INT E - rchild- datatag INT 假如左右孩子为常量合并并且删除常量的结点 else MergeConst E - lchild 递归左孩子 MergeConst E - rchild 递归右孩子
本文档为【表达式类型的实现毕业设计(论文)(已处理)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_721103
暂无简介~
格式:doc
大小:84KB
软件:Word
页数:42
分类:工学
上传时间:2017-11-12
浏览量:26