c语言实现中缀,后缀,前缀表达式转换并求值

合集下载

C++中缀转后缀表达式并求值

C++中缀转后缀表达式并求值

C++中缀转后缀表达式并求值//中缀转后缀#include<iostream>#include<stack>using namespace std;int prio(char x){if(x=='*'||x=='/') return2;if(x=='+'||x=='-') return1;if(x=='(') return0;else return -1;}void in_to_post(char* inorder,char* &post){stack<char>S;int k=0;while(*inorder){//数字if(*inorder>='0'&&*inorder<='9'){post[k++] = *inorder;}//操作符else{if(S.empty()) {S.push(*inorder);}else if(*inorder=='('){S.push(*inorder);}else if(*inorder==')'){while(S.top()!='('){post[k++]=S.top();S.pop();}S.pop();}else{while(prio(*inorder)<=prio(S.top())){post[k++]=S.top();S.pop();if(S.empty()) break;}S.push(*inorder);}}inorder++;}if(!S.empty()){char c =S.top();post[k++] = c;S.pop();}}//后缀表达式求值int cal(int a,int b,char c){if(c=='+') return a+b;else if(c=='-') return a-b;else if(c=='*') return a*b;else if(c=='/') return a/b;else return0;}int postcal(char* post){stack <int > s;while(*post){if(*post >='0'&& *post<='9'){s.push(*post);}else{int a = s.top()-48;s.pop();int b = s.top()-48;s.pop();int c = cal(b,a,*post);s.push(c+48);}post++;}return s.top()-48;}int main(){cout<<"输⼊中缀表达式:"<<endl;char* inorder =new char;cin>>inorder;char* post= new char;cout<<"后缀表达式为:";in_to_post(inorder,post);cout<<post<<endl;int res = postcal(post);cout<<"后缀表达式计算结果:"<<res<<endl;}求解思想:中缀转后缀表达式: 从左到右扫描输⼊的中缀表达式,若是数字,则直接输出到结果,若是运算符则判断: 1. ‘(’ :直接⼊栈; 2. ‘)’:依次把栈中的运算符输出到结果,知道出现‘(’,将左括号从栈中删除; 3. 若是其他运算符,判断当前运算符与栈顶元素的优先级(*/为2,+-为1,(为0,其他为-1),若是当前运算符优先级较⾼,则直接⼊栈,否则,依次输⼊⽐当前运算符优先级⾼或相等的运算符,知道遇到不符合条件的元素或者遇到左括号为⽌,再将当前运算符⼊栈。

栈的应用1——超级计算器(中缀与后缀表达式)C语言

栈的应用1——超级计算器(中缀与后缀表达式)C语言

栈的应⽤1——超级计算器(中缀与后缀表达式)C语⾔这⾥要学的程序主要⽤来实现⼀个功能——输⼊表达式输出结果,也就是⼀个计算器。

效果如下:这个程序主要有两个步骤:1、把中缀表达式转换为后缀表达式;2、计算后缀表达式的结果。

⾸先先明⽩⼏个问题:1、为什么要转换为后缀表达式?因为后缀表达式容易实现计算机计算结果。

(可以百度⼀下后缀表达式,⼜称逆波兰式)2、怎么把中缀表达式转换为后缀表达式?3、怎么⽤后缀表达式输出结果?相信如果弄明⽩了上⾯⼏个问题,有C语⾔基础的同学就可以编出这个程序啦。

⽽后⾯两个问题都要⽤到⼀个数据结构——栈。

实际上数据结构只是⼀种思想,⼀种思维,是连接⼈脑与计算机的桥梁(纯属个⼈杜撰= =) 好,那么我们先学怎么把中缀表达式转换为后缀表达式。

为了简化问题,我们不妨设输⼊的数字都是⼀位整数,这样读⼊的时候只需要以字符的⽅式逐个读⼊即可,也就是说读⼊的必定是数字或者+-*/,读到回车视为结束;另外不妨直接将结果打印到屏幕上,也就是说结果不必存储(这样我们可以更多地关注算法本⾝,⽽⾮输⼊输出⽅式的细枝末节) 类似上⾯的图⽚,它的后缀表达式是 9 3 1 - 2 * + 5 2 / + 怎么得到的呢?下⾯开始讲这个转换的算法: 1、设置⼀个栈,栈底填⼀个"@"作为结束符(当然也可以⽤别的符号,⾄于为什么要⽤⼀会讲优先级的时候会说); 2、开始逐个字符读⼊; 3、如果读⼊的是数字,直接打印printf("%c ",c);(数字后⾯打印⼀个空格作为间隔符,要不然没法看了931-。

不解释) 4、如果读⼊的是"("直接进栈; 5、如果读⼊的是")",说明前⾯肯定读⼊过⼀个"("找到这个左括号,把两者之间的符号逐个弹栈(这⾥要说明的是,括号不必打印,因为后缀表达式没有括号); 6、如果不是上⾯的⼏种情况,那必定是+-*/中的⼀个啦,这样来说就容易多了。

C#算术表达式求值(后缀法),看这一篇就够了

C#算术表达式求值(后缀法),看这一篇就够了

C#算术表达式求值(后缀法),看这⼀篇就够了⼀、种类介绍算术表达式有三种:前缀表达式、中缀表达式和后缀表达式。

⼀般⽤的是中缀,⽐如1+1,前后缀就是把操作符移到前⾯和后⾯,下⾯简单介绍⼀下这三种表达式。

1、前缀表⽰法前缀表⽰法⼜叫波兰表⽰法,他的操作符置于操作数的前⾯(例:+ 1 2),是波兰数学家扬·武卡谢维奇1920年代引⼊的,⽤于简化命题逻辑。

因为我们⼀般认为操作符是在操作数中间的,所以在⽇常⽣活中⽤的不多,但在计算机科学领域占有⼀席之地。

⼀般的表⽰法对计算机来说处理很⿇烦,每个符号都要考虑优先级,还有括号这种会打乱优先级的存在,将使计算机花费⼤量的资源进⾏解析。

⽽前缀表⽰法没有优先级的概念,他是按顺序处理的。

举个例⼦:9-2*3这个式⼦,计算机需要先分析优先级,先乘后减,找到2*3,再进⾏减操作;化成前缀表⽰法就是:- 9 * 2 3,计算机可以依次读取,操作符作⽤于后⼀个操作数,遇到减就是让9减去后⾯的数,⽽跟着9的是乘,也就是说让9减去乘的结果,这对计算机来说很简单,按顺序来就⾏了。

2、中缀表⽰法这也就是我们⼀般的表⽰法,他的操作符置于操作数的中间(例:1 + 2),前⾯也说过这种⽅法不容易被计算机解析,但他符合⼈们的普遍⽤法,许多编程语⾔也就⽤这种⽅法了。

在中缀表⽰法中括号是必须有的,要不然运算顺序会乱掉。

3、后缀表⽰法后缀表⽰法⼜叫逆波兰表⽰法,他的操作符置于操作数的后⾯(例:1 2 +),他和前缀表⽰法都对计算机⽐较友好,但他很容易⽤堆栈解析,所以在计算机中⽤的很多。

他的解释过程⼀般是:操作数⼊栈;遇到操作符时,操作数出栈,求值,将结果⼊栈;当⼀遍后,栈顶就是表达式的值。

因此逆波兰表达式的求值使⽤堆栈结构很容易实现,且能很快求值。

注意:逆波兰记法并不是简单的波兰表达式的反转。

因为对于不满⾜交换律的操作符,它的操作数写法仍然是常规顺序,如,波兰记法/ 6 3的逆波兰记法是6 3 /⽽不是3 6 /;数字的数位写法也是常规顺序。

c语言实现中缀表达式的计算

c语言实现中缀表达式的计算

c语言实现中缀表达式的计算C语言实现中缀表达式的计算一、前言在计算机科学领域,中缀表达式是最容易理解的数学表达式,也是人们最常用的表达方式。

但对于计算机而言,中缀表达式并不方便计算。

因此,在进行表达式计算时,需要将中缀表达式转化为其它形式,例如前缀表达式和后缀表达式。

在本篇文章里,我们将介绍如何使用C语言实现中缀表达式的计算。

二、中缀表达式的转换在C语言中,实现中缀表达式的计算,通常需要先将中缀表达式转换为后缀表达式。

中缀表达式的转换过程主要分为以下三个步骤:1. 初始化一个栈,存储操作符。

2. 遍历中缀表达式,根据操作符的运算优先级将其从中缀表达式转化为后缀表达式。

3. 根据后缀表达式,使用栈实现表达式的计算。

其中,第二步是最关键的一个步骤。

我们可以通过以下方法进行转换:1. 将操作数直接输出。

2. 如果遇到运算符,先将栈中所有优先级大于等于该运算符的操作符弹出,再将该运算符入栈。

3. 如果遇到左括号,直接入栈。

4. 如果遇到右括号,将栈中的元素一直弹出到遇到左括号为止。

例如,对于中缀表达式2 + 3 * 4 - 5,转换为后缀表达式的过程如下所示:中缀表达式:2 + 3 * 4 - 5转换为后缀表达式:2 3 4 * + 5 -三、代码实现现在,我们已经掌握了中缀表达式的转换方法,接下来,我们就可以实现C语言代码了。

具体实现如下:#include <stdio.h>#include <stdlib.h>#include <string.h>// 定义运算符栈char op_stack[100];// 定义数字栈int num_stack[100];// 定义存储后缀表达式的数组char postfix[100];// 定义存储后缀表达式的栈顶指针int postIndex = 0;// 获取优先级int getPriority(char op){switch(op){case '+':case '-':return 1;case '*':case '/':return 2;case '(':case ')':return 0;}return -1;}// 中缀表达式转换为后缀表达式void infixToPostfix(char* infix){// 定义中缀表达式的指针char* ptr = infix;// 定义操作符栈顶指针int opTop = 0;while(*ptr != '\0'){if(*ptr >= '0' && *ptr <= '9') // 如果是数字,直接存入后缀表达式{postfix[postIndex++] = *ptr;}else if(*ptr == '(') // 如果是左括号,先入栈{op_stack[opTop++] = *ptr;}else if(*ptr == ')') // 如果是右括号,将栈中元素全部弹出{while(op_stack[opTop-1] != '('){postfix[postIndex++] = op_stack[--opTop];}opTop--;}else // 如果是运算符{while(opTop > 0 && getPriority(op_stack[opTop-1]) >= getPriority(*ptr)) // 将栈中优先级大于等于当前运算符的元素全部弹出{postfix[postIndex++] = op_stack[--opTop];}op_stack[opTop++] = *ptr; // 将当前运算符入栈}ptr++;}while(opTop > 0) // 将栈中剩余运算符全部弹出{postfix[postIndex++] = op_stack[--opTop];}}// 计算后缀表达式int calculate(char* postfix){// 定义后缀表达式的指针char* ptr = postfix;// 定义数字栈顶指针int numTop = 0;while(*ptr != '\0'){if(*ptr >= '0' && *ptr <= '9') // 如果是数字,直接入栈{num_stack[numTop++] = *ptr - '0';}else // 如果是运算符{int num2 = num_stack[--numTop];int num1 = num_stack[--numTop];switch(*ptr){case '+':num_stack[numTop++] = num1 + num2;break;case '-':num_stack[numTop++] = num1 - num2;break;case '*':num_stack[numTop++] = num1 * num2;break;case '/':num_stack[numTop++] = num1 / num2;break;}}ptr++;}return num_stack[0];}// 测试函数void test(char* infix){printf("中缀表达式:%s\n", infix);infixToPostfix(infix);printf("后缀表达式:%s\n", postfix);int result = calculate(postfix);printf("计算结果:%d\n", result);printf("--------------------------\n");}// 主函数int main(){test("2 + 3 * 4 - 5");test("3 + 4 * 2 / (1 - 5) ^ 2");return 0;}四、总结通过以上代码实现,我们可以看到中缀表达式的计算过程,其实就是将中缀表达式转化为后缀表达式的过程,并使用栈进行计算。

前缀、中缀、后缀表达式的相互转换方法

前缀、中缀、后缀表达式的相互转换方法

前缀、中缀、后缀表达式的相互转换⽅法前缀式、中缀式、后缀式相互转换⼀. 中缀式转化成前缀式和后缀式:⼀个中缀式到其他式⼦的转换⽅法这⾥我给出⼀个中缀表达式a +b *c - (d +e )第⼀步:按照运算符的优先级对所有的运算单位加括号式⼦变成:( ( a + ( b * c ) ) - ( d + e ) )第⼆步:转换前缀与后缀表达式中缀转前缀:把运算符号移动到对应的括号前⾯则变成:- ( + ( a * ( b c ) ) + ( d e ) )把括号去掉:- + a * b c + d e 前缀式⼦出现中缀转后缀:把运算符号移动到对应的括号后⾯则变成:( ( a ( b c ) * ) + ( d e ) + ) -把括号去掉:a b c * + d e + - 后缀式⼦出现⼆. 前缀式转化成中缀式:+ a * b c + d e从后往前遇到运算符,将其与后⾯两个运算数结合,加上括号,当成新的运算数(例如:* b c 加上括号,变成 ( * b c )⼀个整体,作为运算数)变成:( - ( + a ( * b c ) ) ( + d e ) )将运算符加在括号内运算数中间。

变成:( ( a + ( b * c ) ) - ( d + e ) )去掉部分括号:a + b * c - ( d + e )(最后去掉的是不影响运算式含义的多余括号)三. 后缀式转化成中缀式:a b c * + d e + -从前往后遇到运算符,将其与前⾯两个运算数结合,加上括号,当成新的运算数变成:( ( a ( b c * ) + ) ( d e + ) - )将运算符加在括号内运算数中间。

变成:( ( a + ( b * c ) ) - ( d + e ) )去掉部分括号:a + b * c - ( d + e )(最后去掉的是不影响运算式含义的多余括号)。

中缀表达式转后缀表达式并计算结果(c语言版)

中缀表达式转后缀表达式并计算结果(c语言版)

中缀表达式转后缀表达式中缀表达式转后缀表达式的规则。

1.遇到操作数:直接输入到后缀表达式栈2.遇到运算符,直接入操作符栈3.遇到左括号:直接将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。

5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈6.最终将操作符栈中的元素依次出栈,输出到后缀表达式栈。

以下是自己写的代码。

亲测没有问题。

(模拟一个计算器,可以带括号,中间可以空格,只支持整数输入,但是输出结果精确到小数后6位)#include "stdio.h"#define MAX_LEN 100typedef struct cal{unsigned char isOper;//是否是操作数1,操作符0.操作数double Num; //值。

或者是操作符的ASCII值}STRUCT_CAL;#define IS_NUM 0x00#define IS_OPER 0x01STRUCT_CAL stackCal[MAX_LEN];STRUCT_CAL stackCalBack[MAX_LEN];unsigned char topCal;char stackOper[MAX_LEN];unsigned char topOper;/****************************************************************** 堆栈初始化*****************************************************************/void stackInit(void){int i;for(i=0;i<MAX_LEN;i++){stackCal[i].isOper = 0;stackCal[i].Num = 0;stackOper[i] = 0;}topCal = topOper = 0;}/***************************************************************** * 返回堆栈的栈顶,返回后栈顶减一*****************************************************************/ STRUCT_CAL * stackCalPop(void){if(topCal == 0)return (STRUCT_CAL *)0;return stackCal+(--topCal);}/***************************************************************** * 计算表达式入栈*****************************************************************/void stackCalPush(double num, unsigned char isOper){if(topCal>=MAX_LEN)return;stackCal[topCal].Num = num;stackCal[topCal].isOper= isOper;topCal++;}/***************************************************************** * 操作符出栈*****************************************************************/char stackOperPop(void){if(topOper == 0)return 0;return stackOper[--topOper];}/****************************************************************** 操作符入栈*****************************************************************/void stackOperPush(char oper){if(topOper >=MAX_LEN)return;stackOper[topOper++] = oper;}/****************************************************************** 比较两个sour sour1 的优先级* 1 sour >= sour1 直接入操作符栈* 0 sour < sour1 直接入计算表达式栈*****************************************************************/ unsigned char comparPrior(char sour, char sour1){if(sour =='\0' ||sour1 == '\0') return 1;switch(sour){case '+':case '-':if(sour1 == '*' ||sour1 == '/'||sour1 == '+' ||sour1 == '-' ){return 0;}else{return 1;}break;case '*':case '/':if(sour1 == '*' ||sour1 == '/'||sour1 == '+' ||sour1 == '-'||sour1 == '('){return 1;}else{return 0;}break;default:return 1;break;}}/****************************************************************** 将输入的字符串转换为栈*****************************************************************/void StrToCal(char *pStr){int tmpNum = 0;char tmpOper;char islastNum = 0;//判断上一个字符是什么。

c语言基于二叉树的表达式求值算法

c语言基于二叉树的表达式求值算法

c语言基于二叉树的表达式求值算法C语言中,基于二叉树的表达式求值算法主要包括两部分:中缀表达式转换为后缀表达式和后缀表达式求值。

1.中缀表达式转换为后缀表达式中缀表达式是我们常见的数学表达方式,例如3 + 4 * 2 - 5。

为了方便计算机求值,我们需要将中缀表达式转换为后缀表达式,也叫做逆波兰表达式。

转换的过程使用栈数据结构来实现。

具体算法如下:1.定义一个栈和一个结果字符串,栈用于存储操作符,结果字符串用于保存后缀表达式。

2.从左到右遍历中缀表达式的每一个字符。

3.如果当前字符是数字,直接将其加入结果字符串。

4.如果当前字符是左括号"(",将其入栈。

5.如果当前字符是右括号")",则依次将栈顶的操作符弹出并加入结果字符串,直到遇到左括号为止,同时将左括号从栈中弹出。

6.如果当前字符是操作符,需要将栈中优先级比当前操作符高或者相等的操作符弹出并加入结果字符串,然后将当前操作符入栈。

7.遍历完所有字符后,将栈中剩余的操作符依次弹出并加入结果字符串。

8.最终结果字符串就是后缀表达式。

例如,对于中缀表达式3 + 4 * 2 - 5,转换为后缀表达式为3 4 2 * + 5 -2.后缀表达式求值后缀表达式求值算法使用栈数据结构来实现。

具体算法如下:1.定义一个栈,用于存储操作数。

2.从左到右遍历后缀表达式的每一个字符。

3.如果当前字符是数字,则将其转换为对应的整数并入栈。

4.如果当前字符是操作符,则从栈中弹出两个操作数,先弹出的作为右操作数,后弹出的作为左操作数,根据操作符进行运算,得到结果后入栈。

5.遍历完所有字符后,栈顶的数字即为最终的结果。

例如,对于后缀表达式3 4 2 * + 5 -,求值的过程如下:1.入栈3。

2.入栈4。

3.入栈2。

4.弹出2和4,计算4 * 2 = 8,将8入栈。

5.弹出8和3,计算3 + 8 = 11,将11入栈。

6.入栈5。

7.弹出5和11,计算11 - 5 = 6,得到最终结果。

前缀、中缀、后缀表达式的转换(栈)

前缀、中缀、后缀表达式的转换(栈)

前缀、中缀、后缀表达式的转换(栈)
前缀表达式:op a b
中缀表达式:a op b
后缀表达式 a b op
1、对于计算单独的后缀表达式较为简单,从左到右,遇到数字将其压⼊栈内,遇到操作符从栈中取出两个数进⾏相应操作,结果再次压⼊栈内。

2、对于前缀表达式的计算和后缀相似,从右到左的顺序,剩下和后缀⼀致
3、对于中缀表达式,我们可以选择将其转换成前缀或者后缀表达式。

中缀转后缀:(从左到右)
1、遇到⼀个数字就输出(毕竟不管中缀和后缀,都只是操作符位置的改变,和数字⽆关)
2、遇到‘( ’直接压⼊栈
3、遇到’ )‘将栈中操作符输出,直到输出’( ‘ (括号内相当于另⼀个后缀表达式,当遇到’)‘时,就将括号内的符号都输出)
4、遇到操作符,将栈中优先级不低于的符号输出,然后将操作符压⼊栈(乘除 > 加减 > 左括号)(因为优先级⾼的需要先运算,优先级相同的因为先出现所以先运算)
5、最后输出栈中剩下的所有操作符
中缀转前缀:(从右到左)
1、遇到⼀个数字就输出到临时栈(毕竟不管中缀和前缀,都只是操作符位置的改变)
2、遇到‘ ) ’直接压⼊符号栈
3、遇到’ (‘将符号栈中操作符输出,直到输出’) ‘
4、遇到操作符,将栈中优先级⼤于的符号输出,然后将操作符压⼊符号栈(乘除 > 加减 > 右括号)
(优先级相同之所以不出栈,因为输出的前缀时倒序的,优先级相同应该在更后⾯输出,这样倒过来才是最前⾯)
5、最后输出符号栈中剩下的所有操作符⾄临时栈
6、然后输出临时栈中的结果(输出出来的才是前缀表达式)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

c语言实现中缀,后缀,前缀表达式转换并求值c语言实现中缀,后缀,前缀表达式转换并求值九#include #include #define MAXNUM 100 typedef struct Node//定义存储中缀表达式的结点类型{int data; int data1; char data2; struct Node *next; }Lnode; typedef struct Node2//定义存储前缀表达式的结点类型{int data; int data1; char data2; struct Node2 *next; struct Node2 *prior; }Lnode2; typedef int selemtype1;//定义运算数栈的结点typedef struct//定义运算数栈的类型{selemtype1 *base; selemtype1 *top; }sqstack1; void InitStack1(sqstack1 &s)//新建一个空运算数栈{=(selemtype1 *)malloc(MAXNUM*sizeof(selemtype1));=; if(!) printf(“出错:申请空间失败!\\n”); } void Push1(sqstack1 &s,selemtype1 &e)//运算数栈,入栈:插入元素e为新的栈顶元素{ if(>=MAXNUM) printf(“出错:表达式过长!1\\n”); *++ =e; } void GetTop1(sqstack1 s,selemtype1 &e)//运算数栈,用e返回栈顶元素{e=*(); } void Popopnd1(sqstack1 &s,selemtype1 &e) //运算数栈,退栈:删除栈顶元素,并用e返回其值{e=*--; } int stackempy1(sqstack1 s) //运算数栈,若为空栈返回1,否则返回0 {if(==) return 1; else return 0; } typedef char selemtype2;//定义运算符栈的结点类型typedef struct//定义运算符栈类型{selemtype2 *base; selemtype2 *top; }sqstack2; void InitStack2(sqstack2 &s)//新建一个空运算符栈{=(selemtype2 *)malloc(MAXNUM*sizeof(selemtype2)); =; if(!) printf(“出错:申请空间失败!\\n”); } void Push2(sqstack2 &s,selemtype2 &e)//运算符栈,入栈:插入元素e为新的栈顶元素{ if(>=MAXNUM) printf(“出错:表达式过长!2\\n”); *++ =e; } void GetTop2(sqstack2 s,selemtype2 &e)//运算符栈,用e返回栈顶元素{e=*(); } void Popopnd2(sqstack2 &s,selemtype2 &e) //运算符栈,退栈:删除栈顶元素,并用e返回其值{e=*--; } int stackempy2(sqstack2 s) //运算符栈,若为空栈返回1,否则返回0 {if(==) return 1; else return 0; } void priority(char c,int &i)//确定运算符优先级{if (c==‘*’||c==‘/’||c==‘%’) i=2 ; else if (c==‘+’||c==‘-’) i=1 ; else i=0; } int compare(char a,char b)//比较栈顶元素运算符与外部运算符优先级大小,外部优先级大则返回1,反之返回0 {int in,out; priority(a,in); priority(b,out); if(out>in) return 1; else return 0; } void Operat(sqstack1 &OPND,sqstack2&OPTR) {int num1,num2,num; char c; Popopnd1(OPND,num2);Popopnd1(OPND,num1);Popopnd2(OPTR,c); switch(c) {case ‘+’:num=num1+num2;break; case ‘-’:num=num1-num2;break; case ‘*’:num=num1*num2;break; case ‘/’:num=num1/num2;break; case ‘%’:num=num1%num2;break; } Push1(OPND,num); } void Operatqianzhui(sqstack1 &OPND,sqstack2 &OPTR) {int num1,num2,num; char c; Popopnd1(OPND,num1);Popopnd1(OPND,num2);Popopnd2(OPTR,c); switch(c) {case ‘+’:num=num1+num2;break; case ‘-’:num=num1-num2;break; case ‘*’:num=num1*num2;break; case ‘/’:num=num1/num2;break; case ‘%’:num=num1%num2;break; } Push1(OPND,num); }voidhouzhuiqiuzhi(Lnode *p,int &e) {sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n; char c; p=p->next; InitStack1(OPND); InitStack2(OPTR); while(p) {switch(p->data) {case 1:n=p->data1; Push1(OPND,n); break; case 2:c=p->data2; Push2(OPTR,c); Operat(OPND,OPTR); break; default:printf(“结点有误”); brea k; } p=p->next; } Popopnd1(OPND,n); e=n; } void zhongzhui(Lnode *p) {sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n; //后缀表达式求值//中缀表达式求值char c,c2; Lnode *first; first=p; p=p->next; InitStack1(OPND); InitStack2(OPTR); while(!stackempy2(OPTR)||p) {while(p) {switch(p->data) {case 1:n=p->data1; Push1(OPND,n); break; case 2:c=p->data2; if(stackempy2(OPTR)) Push2(OPTR,c); else { switch(c){case ‘(‘: Push2(OPTR,c);break; case ‘)’: GetTop2(OPTR,c2); while(c2!=‘(‘) {Operat(OPND,OPTR);GetTop2(OPTR,c2);}Popopnd2(OPTR,c2); break; default: GetTop2(OPTR,c2);if(compare(c2,c)) Push2(OPTR,c); else { Operat(OPND,OPTR); Push2(OPTR,c); } break; } } break; default: printf(“结点有误”); break; } p=p->next; } while(!stackempy2(OPTR))Operat(OPND,OPTR); } Popopnd1(OPND,n); p=first->next; while(p) {if(p->data==1) printf(“%d “,p->data1); if(p->data==2) printf(“%c”,p->data2);p=p->next; } printf(“=%d “,n); }void houzhui(Lnode *p)//中缀表达式转化为后缀表达式{sqstack2OPTR; //运算符栈Lnode *r,*q,*head; int n; char c,c2; InitStack2(OPTR); p=p->next;q=(Lnode*)malloc(sizeof(struct Node)); head=q; while(p) { switch(p->data) {case 1:n=p->data1; r=(Lnode*)malloc(sizeof(struct Node)); q->next=r; q=q->next; q->data=1; q->data1=n; break; case 2:c=p->data2; if(stackempy2(OPTR)) Push2(OPTR,c); else { switch(c) { case ‘(‘: Push2(OPTR,c);break; case ‘)’: Popopnd2(OPTR,c2); while(c2!=‘(‘) { r=(Lnode*)malloc(sizeof(struct Node)); q->next=r; q=q->next; q->data=2; q->data2=c2; Popopnd2(OPTR,c2); } break; default: GetTop2(OPTR,c2); while(!compare(c2,c)){ Popopnd2(OPTR,c2); r=(Lnode*)malloc(sizeof(struct Node)); q->next=r; q=q->next; q->data=2; q->data2=c2; GetTop2(OPTR,c2); }Push2(OPTR,c); break; } } break; default: printf(“结点有误”); break; } p=p->next; } while(!stackempy2(OPTR)){ Popopnd2(OPTR,c2); r=(Lnode*)malloc(sizeof(struct Node)); q->next=r; q=q->next; q->data=2; q->data2=c2; } q->next=NULL; q=head->next; while(q) {if(q->data==1) printf(“%d “,q->data1); if(q->data==2) printf(“%c”,q->data2); q=q->next; } houzhuiqiuzhi(head,n); printf(“=%d “,n); } void qianzhuiqiuzhi(Lnode2 *p,int &e) //前缀表达式求值{sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n; char c; Lnode2 *head; head=p; p=p->next; InitStack1(OPND); InitStack2(OPTR); while(p!=head) {switch(p->data) {case 1:n=p->data1; Push1(OPND,n); break; case 2:c=p->data2; Push2(OPTR,c);Operatqianzhui(OPND,OPTR); break; default:printf(“结点有误”); break; } p=p->next; } Popopnd1(OPND,n); e=n; }void qianzhui(Lnode *p)式{sqstack2 OPTR; //运算符栈InitStack2(OPTR); int n; char c,c2; Lnode *first; Lnode2 *q,*head,*r,*head2,*s; first=p; p=p->next; q=(Lnode2*)malloc(sizeof(struct Node2)); //中缀表达式转化为前缀表达//建立存中缀表达式的双向循环链表head=q; while(p) {r=(Lnode2*)malloc(sizeof(struct Node2)); q->next=r; r->prior=q; q=q->next; q->data=p->data; q->data1=p->data1; q->data2=p->data2; p=p->next; } q->next=head; head->prior=q; s=(Lnode2*)malloc(sizeof(struct Node2)); //建立存前缀表达式的双向循环链表head2=s; while(q!=head) {switch(q->data) {case 1:n=q->data1; r=(Lnode2*)malloc(sizeof(struct Node2)); s->next=r; r->prior=s; s=s->next; s->data=1; s->data1=n; break; case 2:c=q->data2; if(stackempy2(OPTR)) Push2(OPTR,c); else { GetTop2(OPTR,c2); if(c2==‘)’) Push2(OPTR,c); else{ switch(c) { case ‘)’:Push2(OPTR,c);break; case ‘(‘: Popopnd2(OPTR,c2); while(c2!=‘)’) { r=(Lnode2*)malloc(sizeof(struct Node2)); s->next=r; r->prior=s; s=s->next; s->data=2; s->data2=c2; Popopnd2(OPTR,c2); } break; default: GetTop2(OPTR,c2); while(!compare(c2,c)){ Popopnd2(OPTR,c2); r=(Lnode2*)malloc(sizeof(struct Node2)); s->next=r; r->prior=s; s=s->next; s->data=2; s->data2=c2; GetTop2(OPTR,c2); } Push2(OPTR,c); break; } } } break; default:printf(“结点有误”); break; }q=q->prior; } while(!stackempy2(OPTR)){ Popopnd2(OPTR,c2); r=(Lnode2*)malloc(sizeof(struct Node2)); s->next=r; r->prior=s; s=s->next; s->data=2; s->data2=c2; } s->next=head2; head2->prior=s; while(s!=head2) {if(s->data==1) printf(“%d “,s->data1);if(s->data==2) printf(“%c”,s->data2); s=s->prior; } qianzhuiqiuzhi(head2,n); printf(“=%d “,n);}int main() { char n[10]; char c; int i,j,k,a,b,z,y,e; Lnode *p,*q,*first; i=0;e=1;a=0;b=1;z=0;y=0;p=(Lnode*)malloc(sizeof(struct Node)); first=p; printf(“请输入中缀表达式”); do { c = getchar(); if(‘0’{ switch (c) { case ‘+’: case ‘-’: case ‘*’: case ‘/’: case ‘%’: case ‘(‘:case ‘)’: case ‘\\n’: { if(n[0]>‘0’&&n[0]next=q; p=p->next; for(k=0;k{ for(j=0;j a=a+(n[k]-’0’)*e; e=1; n[k]=‘0’; } p->data=1; p->data1=a; i=0;a=0; } if(c!=‘\\n’) { if(p->data==2) { if(p->data2!=‘)’&&c!=‘(‘) b=0; } q=(Lnode*)malloc(sizeof(struct Node)); p->next=q; p=p->next; p->data=2; p->data2=c; if(c==‘(‘) z++; if(c==‘)’) y++; } } default: if(c!=‘+’&&c!=‘-’&&c!=‘*’&&c!=‘/’&& c!=‘%’&&c!=‘\\n’&&c!=‘(‘&&c!=‘)’)b=0; } } }while (c != ‘\\n’); if(z!=y) b=0; p->next=NULL; if(b==0) printf(“输入中缀表达式有误”); else {printf(“输入1中缀表达式求值,输入2后缀表达式求值,输入3前缀表达式求值”); scanf(“%d”,&b); if(b==1) zhongzhui(first); if(b==2) houzhui(first); if(b==3) qianzhui(first); } return 1; }。

相关文档
最新文档