1、2下面给出得到后缀表达式的算法流程图:图2 得到后缀表达式的算法流程图图2是通过用户输入的表达式得到其后缀表达式的算法流程图,整体描述了得到后缀表达式的过程,但是还有一些细节并没有刻画出来。其中,大方向有两个分支,就是判断进来的字符是否为数字,然后,当得知进来的字符不是数字时,又分成了两个分支,即判断该字符是否为运算操作符或是左括号,因为他们的操作基本类似;第二分支就是进来的字符为右括号。3下面给出通过后缀表达式得到计算结果的算法流程图:图3 通过后缀表达式得到结果的算法流程图图3是通过后缀表达式得到最终计算结果的算法流程图,其中,当整个后缀表达式遍历完成后,我们的数字栈中只会剩下一个Node
2、元素,这个元素即为最终计算的结果。4下面给出一步直接计算表达式的算法流程图:图4 一步直接计算表达式得到结果的算法流程图图4是一步直接计算表达式得到结果的算法流程图,其核心思想和得到后缀表达式基本类似,不同之处是,如果遍历过程中遇到了数字,将数字入数字栈,而当遇到操作符后,如果优先级小,那么直接从数字栈依次取出两个栈顶数字,进行计算,将计算的结果再次入数字栈。三、源代码 下面给出计算表达式的原代码,两种方法写在了一个程序里面,其中有个GetHzbdsByExpr的方法,是得到后缀表达式的方法,有个GetResultByListNode的方法,是通过后缀表达式得到计算结果的方法,然后有个GetR
3、esultWithOneStep的方法,是一步直接计算结果的方法,都有注释标识。源代码:#include stdio.hconio.hstring.hstdlib.hstruct Node *listNode100;/*定义一个长度为100的Node类型的数组,用来存放转换完成的后缀表达式*/typedef struct Node/*定义Node类型的结构体,用来代表数字和操作符*/ char op;/*操作符的字符*/ int level;/*操作符的优先级*/ float od;/*数字的值*/ int type;/*Node的类型标识符*/Node;void initNode(Node*
4、 nd,char c,int le,float val,int ty)/*初始化Node*/ nd-op=c;/*操作符的字符,赋值为传过来的字符*/level=le;/*操作符的优先级 ,赋值为传过来的优先级级别*/od=val;/*赋值为传过来的浮点数数值*/type=ty;/*赋值标识符*/typedef struct MyStack/*定义一个栈的结构体,用来存放操作符和数字*/ Node* listNd100;/*定义一个长度为100的node类型的数组,用来当做栈*/ int top;/*栈顶索引*/ MyStack;void initMyStack(MyStack* ms)/*初
5、始化栈*/ ms-top=0;/*初始化的时候栈顶指向0*/int IsEmpty(MyStack* ms)/*判断栈是否为空*/ if(ms-top=0) return 0;/*0代表为空*/ return 1;void Push(Node* nd,MyStack* ms)/*向ms栈中追加一个node类型的nd*/listNdms-top=nd;/*追加node*/top+;/*将栈顶索引指向下一项*/Node* Pop(MyStack* ms)/*从ms栈中取出栈顶的node*/top != 0)/*如果栈不为空*/ top-;/*将栈顶索引指向上一项*/ return ms-top;/
6、*返回栈顶node*/ return NULL;/*如果栈为空,那么返回NULL*/Node* Top(MyStack* ms)/*观察栈顶的node*/ int top = ms-top;/*获得当前的栈顶索引*/ Node *topNode;/*定义一个node*/ if(top != 0) topNode = ms-listNdtop-1 ;/*得到栈顶的Node*/ return topNode;/*返回栈顶Node*/ elsechar * cutStr(char * expr,int begin,int end)/*截取字符串的方法,从begin开始,截取到end*/ char *
7、result = NULL;/*定义截取到的结果字符数组*/ int resultCount = 0;/*要截取的字符串的长度*/ resultCount = end - begin + 1;/*截的末尾索引减去起始索引加1即为要截取的长度*/ result = (char *)malloc(sizeof(char) * resultCount + 1);/* 多申请一个字节,用于存放结束句0 */ if(result = NULL)/*如果没有开辟成功空间*/ printf(Error malloc memory in function.n);/*打印开辟内存空间错误*/ strncpy(r
8、esult, expr + begin, resultCount);/*从expr+begin这个地址开始,截取resultCount个字符赋给result*/ resultresultCount = ;/*赋值结果字符数组的最后一位为0*/ return result;void GetHzbdsByExpr(char * expr)/*得到后缀表达式的方法*/ int index=0,indexnow,tempindex=0,i=0,listIndex=0;/*index-主索引;indexnow-在截取字符串时代表当前索引值;tempindex-副索引;i-控制循环;listIndex-后
9、缀表达式的项编号*/ float tempn;/*即时用的数字*/ char str100=;/*截取字符串时用到的临时存放字符的数字*/ char * c=/*主索引遍历时遍历到位置的字符*/ char * tempc=/*即时用的字符*/ struct MyStack *opStack=(MyStack*)malloc(sizeof(MyStack);/*定义一个操作符栈,并为之开辟空间*/ struct Node *node=(Node*)malloc(sizeof(Node);/*定义一个Node元素*/ initMyStack(opStack);/*初始化操作符栈*/ listNod
10、e0=NULL;/*清空存放后缀表达式的数组*/ while(index=0 & *c9) str0=*c;/*把这个字符加到str数组中*/ tempindex=0;/*要截取的字符的长度*/ indexnow=index+1;/*从主索引下一个开始继续遍历*/ tempc = cutStr(expr,indexnow,indexnow);/*主索引的下一个字符*/ while(indexnow) & (*tempc level level) popNode=Pop(opStack);/*如果目前的操作符的优先级小于栈顶操作符的优先级,就将栈顶操作符取出*/ listNodelistInde
11、x=popNode;/*将取出的操作符node放入后缀表达式的数组中*/*继续观察栈顶操作符*/*后缀表达式数字加一位*/*当目前的操作符的优先级大于栈顶操作符的优先级时,将目前的操作符入操作符栈*/*/% initNode(tempNode,*c,2,-100,2);/*2代表、的优先级,比的优先级高*/( initNode(tempNode,*c,-1,-100,2);/*左小括号的优先级为-1*/*左小括号直接入栈*/) topNode = Top(opStack);/*得到栈顶*/ while(IsEmpty(opStack) = 1 & (topNode-op != )/*观察栈顶,
12、如果栈顶不是左括号*/*取出栈顶*/*加到后缀表达式中*/*继续观察栈顶*/ Pop(opStack);/*当工作完成后,栈顶一定是一个左括号,直接扔掉*/ initNode(tempNode,*c,-2,-100,2);/*左中括号的优先级为-2*/*左中括号直接入栈*/ initNode(tempNode,*c,-3,-100,2);/*左花括号的优先级为-3*/*左花括号直接入栈*/ while(IsEmpty(opStack)=1)/*当遍历的工作做完之后,如果操作符栈不为空*/ popNode = Pop(opStack); listNodelistIndex=NULL;/*当得到后
13、缀表达式之后,将最后一个node的下一位赋空。*/Postfix expression is : n/*输出:“后缀表达式为:”*/ for(i=0;itype = 1)/*如果node的type=1,即node是数值,则输出node的数值*/%.2f |,node-od);type = 2)/*如果node的type=2,即node是操作符,则输出node的字符*/%c |op);float GetResultByListNode()/*通过后缀表达式得到结果的方法*/ float result=0;/*定义最终计算的结果,用于方法返回*/ int i=0;/*控制循环*/ float od
14、a=0,odb=0,odResult=0;/*oda,odb-栈顶的两个数字,odResult-两个数字的计算结果*/*定义一个Node元素并开辟内存空间*/ struct MyStack *odStack=(MyStack*)malloc(sizeof(MyStack);/*定义数字栈并开辟空间*/ initMyStack(odStack);/*初始化数字栈*/listNodei != NULL;i+)/*遍历后缀表达式中每一个node*/*得到第i个node*/type = 1) Push(node,odStack);/*如果node的类型是数值,那么入数栈*/type = 2) struct Node *odNode=(Node*)malloc(sizeof(Node); char c = node-op; switch(c)/*判断操作符*/ case : oda=Pop(odStack)-od;/*从栈顶取出一个数值作为加数*/ odb=Pop(odStack)-/*再从栈顶取出一个数值为被加数*/ odResult=odb+oda;/*计算两个数字*/ initNode(odNode,-100,odResult,1); Push(odNode,odStack);/*将计算结果再次入数栈*/ break;/*从栈顶取出一个数值作为减数*/*再从栈顶取
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2