1、实验三实验报告1120131317 周任然1、简易计算器(1 )问题描述由键盘输入一算术表达式,以中缀形式输入,试编写程序将中缀表达式转换成一棵二叉表达式树,通过对该的后序遍历求出计算表达式的值。(2 )基本要求 a要求对输入的表达式能判断出是否合法。不合法要有错误提示信息。b将中缀表达式转换成二叉表达式树。c后序遍历求出表达式的值(3 )数据结构与算法分析一棵表达式树,它的树叶是操作数,如常量或变量名字,而其他的结点为操作符。a建立表达式树。二叉树的存储可以用顺序存储也可用链式存储。当要创建二叉树时,先从表达式尾部向前搜索,找到第一个优先级最低的运算符,建立以这个运算符为数据元素的根结点。注
2、意到表达式中此运算符的左边部分对应的二叉绔为根结点的左子树,右边部分对应的是二叉绔为根结点的右子树,根据地这一点,可用递归调用自己来完成对左右子树的构造。b求表达式的值。求值时同样可以采用递归的思想,对表达式进行后序遍历。先递归调用自己计算左子树所代表的表达式的值,再递归调用自己计算右子树代表的表达式的值,最后读取根结点中的运算符,以刚才得到的左右子树的结果作为操作数加以计算,得到最终结果。(4 )需求分析程序运行后显示提示信息,输入任意四则运算表达式,倘若所输入的表达式不合法程序将报错。输入四则运算表达式完毕,程序将输出运算结果。测试用的表达式须是由+ 、- 、*、/运算符,括号“(” 、
3、“)”与相应的运算数组成。运算数可以是无符号浮点型或整型,范围在 065535。(5 )概要设计二叉树的抽象数据类型定义ADT BinaryTree数据对象:表达式运算数 num | 0=0 ; i-) /对输入串逆序扫描if(Str.chi=48break; else Pop(S , e);Output.chi=e; Output.length+; if( Str.chi=( ) /假如是左括号,栈中运算符逐个出栈并输出,直到遇到右括号。右括号出栈并丢弃。while( GetTop(S)!=) ) Output.chi=Pop(S);Output.length+; while(S.top!=
4、-1) /假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。Output.ch=Output.ch-; Output.ch=Pop(S); return output;void CreatBiTree( SqStack Sq; /用以存放生成的二叉树结点InitStack(Sq);F=Convert(S); /求得 S 的前缀表达式for(i=F.length-1 ; i=0 ; i-) If( !IsOperator(F.chi) ) T=new TNode;T-data=F.chi;T-lchild=NULL;T-rchild=NULL;Push(Sq , T) else T=new
5、TNode;T-data=F.chi;T-lchild=Pop( Sq );T-rchild=Pop( Sq );Push(Sq , T); int Calc(int a, char opr, int b) /计算switch (opr) case +: return a + b;case -: return a - b;case *: return a * b;case /: return a / b; int Value(TNode *T) if (T-lchild = NULL elsereturn Calc( Value(T-lchild) , T-data , Value(T-rch
6、ild) );主函数伪码算法。void main() Face(); /输出界面及相关信息do coutStr;JudgeExp(S); /判断输入的表达式是否合法。 T=CreatBiTree(S);N=Value(T); coute; if(e=y) flag=1;else flag=0; while(flag)/main测试结果附录(带注释的源程序)/*CStack.h*/#includeusing namespace std;#define Stack_Size 100typedef struct /字符类型顺序栈char elemStack_Size;int top;CStackvo
7、id InitCStack(if(!S.elem) Error(“Overflow!“);S.top=-1;void Push_C(CStack S.elem+S.top=e;char Pop_C(CStack return S.elemtop-;char GetTop(return S.elemtop;int CStackLength(/*TStack.h*/#include#include“Tree.h“using namespace std;#define Stack_Size 100typedef struct /二叉树结点类型顺序栈TNode elemStack_Size;int t
8、op;TStackvoid InitTStack(if(!S.elem) Error(“Overflow!“);S.top=-1;void Push_T(TStack S.elem+S.top=T;TNode Pop_T(TStack return S.elemtop-;/*String.h*/#includeusing namespace std;typedef struct /动态顺序串char *ch;int len;StringSrting StrNeg(for(i=0 ; i#include“String.h“#include“CStack.h“#include“TStack.h“u
9、sing namespace std;typedef struct /二叉树结点union data /数据域char opr; /运算符int opn; /运算数struct TNode *lchid , *rchild; /指针域TNodetypedef TNode *BiTree; /二叉树头结点int Precedence(char opr) /判断运算符级别函数;其中* /的级别为 2, + -的级别为 1;switch(opr)case+: case-: return 1; break;case*: case/: return 2; break;case(: case):case#
10、:default:return 0; break;bool IsOperator(char opr) /判断输入串中的字符是不是合法操作符if(op=+|op=-|op=*|op=/)return true;elsereturn false;String Convert(String String Output; /输出串Output.len=0;CStack S;InitCStack(S);Str.len=StrLen(Str); /求的输入的串长for(i=Str.len-1 ; i=0 ; i-) /对输入串逆序扫描if(Str.chi=48 break;elseOutput.chStr
11、.len-1-i=Pop_C(S);Output.len+;if( Str.chi=( ) /假如是左括号,栈中运算符逐个出栈并输出 /直到遇到右括号。右括号出栈并丢弃。while( GetTop(S)!=) )Output.chStr.len-1-i=Pop_C(S);Output.len+;while(S.top!=-1) /假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。Output.ch+Output.len-1=Pop_C(S);return StrNeg(Output); /输出 Output 的逆序即为所求前缀表达式void CreatBiTree(TStack S; /用
12、以存放生成的二叉树结点InitTStack(S);F=Convert(Str); /求得 S 的前缀表达式for(i=F.len-1 ; i=0 ; i-)if( !IsOperator(F.chi) )T=new TNode;T-data=F.chi;T-lchild=NULL;T-rchild=NULL;Push_T(S , T)elseT=new TNode;T-data=F.chi;T-lchild=Pop_T( S );T-rchild=Pop_T( S );Push_T(S , T);int Calc(int a, char opr, int b) /计算switch (opr)c
13、ase +: return a + b;case -: return a - b;case *: return a * b;case /: return a / b;int Value(TNode *T) /求表达式二叉树的值if (T-lchild = NULL elsereturn Calc( Value(T-lchild) , T-data , Value(T-rchild) );/*JudgeExp.h*/#include#include“String.h“#include“Tree.h“using namespace std;bool JudegExp(String Exp) /此函
14、数验证式子是否正确,即是否符合运算规则。char check;int error=0;int lb=0;int rb=0;if(StrLen(Exp)=1 else if( (IsOperator(Exp.ch0)for(int m=0 ; m#include“CStack.h“#include“TStack.h“#include“String.h“#include“Tree.h“#include“JudgeExp.h“using namespace std;void Face() /输出简单界面即信息coutStr;JudgeExp(Str); /判断输入的表达式是否合法。T=CreatBiTree(Str); /生成表达式二叉树n=Value(T); /计算表达式的值coute;if(=y) flag=1;else flag=0; while(flag)