数据结构之中缀表达式转后缀表达式

合集下载

将中缀表达式转换成后缀表达式的三种方法

将中缀表达式转换成后缀表达式的三种方法

将中缀表达式转换成后缀表达式的三种方法中缀表达式是我们平常最常见的表达式形式,但在计算机的运算过程中,我们常常需要将中缀表达式转换成后缀表达式,因为后缀表达式具有易于计算的特点。

那么,接下来我们将介绍三种将中缀表达式转换成后缀表达式的方法。

一、栈的方法这种方法是最常见的一种方法,也是比较易理解的一种方法。

我们可以借助栈来完成中缀表达式转换成后缀表达式的过程。

具体的操作如下:1. 声明一个操作符的栈stack(栈中存放操作符)和一个后缀表达式的列表res(列表中存放转换后的后缀表达式)。

2. 从左到右遍历中缀表达式。

3. 若当前字符为数字,则直接将该数字添加到res中。

4. 若当前字符为左括号“(”,则将其压入stack栈中。

5. 若当前字符为右括号“)”,则依次弹出stack栈中的操作符并加入到res中,直到遇到左括号为止。

6. 若当前字符为操作符,那么则需判断当前操作符与stack栈顶操作符的优先级,若当前操作符的优先级小于等于栈顶操作符,则弹出栈顶操作符并加入到res中,重复此步骤,直到当前操作符大于栈顶操作符优先级,最后将当前操作符压入stack栈。

7. 当遍历完整个中缀表达式后,若stack栈中还有剩余操作符,则依次弹出栈顶操作符并加入到res中。

8. 最终,res中的表达式就是转换后的后缀表达式。

二、递归调用方法这种方法是使用递归的方式来完成。

具体的操作如下:1. 若当前遍历的字符为数字,则直接输出该数字。

2. 若当前遍历的字符为左括号“(”,则递归读取该括号内的表达式。

3. 若当前遍历的字符为右括号“)”,则返回。

4. 若当前遍历的字符为操作符,“x”,“/”,“+”,“-”,则递归调用该表达式右边的操作符,比如“x”,“/”,然后再递归调用左边的操作符,比如“+”,“-”,然后输出左操作数和右操作数,最后输出当前操作符。

5. 最终,输出的表达式即为转换后的后缀表达式。

三、判断法这种方法也是比较常见的一种方法。

数据结构中缀表达式改后缀表达式

数据结构中缀表达式改后缀表达式
例如,整个 表达式的括号要省略,不影响计算顺序括号要省略。 输入形式:
程序从标准输入读入一行字符串,是一个合法的后缀表达式,数字和运 算符之间
由空格分隔。数字可以是带小数部分的浮点数。
输出形式: 向标准输出打印结果,输出只有一行,是转换后的中缀表达式。 并且 : 1、各分量(包括括号)紧密输出,不使用空格进行分隔; 2、在转换后的各运算数的出现顺序不变; 3、浮点数保留输入时的小数位数。
Node p,q,f;
//连接两个链表
if(flag==0) {
printf("错误\n"); exit(0); }
E->Lists[flag-1]->c=ch;
p=E->Lists[flag-1]; f=E->Lists[flag]->next;
while(p->next!=NULL) p=p->next;
*/
#include<stdio.h> #include<stdlib.h>
struct Expression; typedef struct Expression *Node;
struct Expressionlist; typedef struct Expressionlist *Elist;
struct Expression {
7. 之后是符号“+”,此时当前栈顶元素比这个“+”的优先级高,因此栈中元素出 栈并输出(没有比“+”号更低的优先级,所以全部出栈),总输出表达式为 9 3 1 - 3 * +.然后将当前这个符号“+”进栈。也就是说,前 6 张图的栈底的“+”是指中缀 表达式中开头的 9 后面那个“+”,而下图中的栈底(也是栈顶)的“+”是指 “9+(3-1)*3+”中的最后一个“+”。 8. 紧接着数字 10,输出,总表达式变为 9 3 1-3 * + 10。

算术表达式(中缀表达式)转换为后缀表达式

算术表达式(中缀表达式)转换为后缀表达式

算术表达式(中缀表达式)转换为后缀表达式将后缀表达式exp转换为postexp的过程如下:while(从exp读取字符ch,ch!='\0'){ 若ch为数字,将后继的数字都⼀次存放到postexp中,并以字符'#'标志数值串的结束; 若ch为左括号“(”,将此括号进栈到运算符栈op中; 若ch为右括号“)”,将运算符栈op依次出栈,直到“(”,并将“(”也出栈; 若ch为运算符,优先级不⼤于运算符op的栈顶运算符(除栈顶运算符为“(”外)的优先级,则依次出栈并存⼊到postexp中,然后将ch 进栈}若中缀表达式exp扫描完毕,将运算符栈op中的所有运算符依次出栈并存放到postexp中,就得到了后缀表达式。

完整代码:#include <stdio.h>#define MAXSIZE 50typedef char elemType;//运算符栈typedef struct{elemType data[MAXSIZE];int top;}OP;OP op;//中缀表达式转为后缀表达式void trans(char exp[],char postexp[]){op.top=-1;int i=0,j=0;char ch=exp[i];while(ch!='\0'){switch(ch){case'(':{op.top++;op.data[op.top] = ch;break;}case')':{while(op.data[op.top]!='('){postexp[j++]=op.data[op.top--];}op.top--; //去除 '('break;}case'+':case'-':{while(op.top!=-1&&op.data[op.top]!='('){postexp[j++]=op.data[op.top--];}op.top++;op.data[op.top]=ch;break;}case'*':case'/':{while(op.top!=-1&&(op.data[op.top]=='*'||op.data[op.top]=='/')){postexp[j++]=op.data[op.top];op.top--;}op.top++;op.data[op.top]=ch;break;}case'':break;default :{while(ch>='0'&&ch<='9'){postexp[j++]=ch;i++;ch=exp[i];}i--; //不是数字退后⼀个,⽤switch来进⾏判断 postexp[j++]='#'; //在数字结束后添加'#'以便区分}}i++;ch=exp[i];}while(op.top!=-1){ //将运算符栈中postexp[j++]=op.data[op.top--];}postexp[j]='\0';}。

中缀表达式转后缀表达式

中缀表达式转后缀表达式

中缀表达式转后缀表达式逆波兰表达式先说⼀下中缀表达式,平时我们使⽤的运算表达式就是中缀表达式,例如1+3*2,中缀表达式的特点就是:⼆元运算符总是置于与之相关的两个运算对象之间⼈读起来⽐较好理解,但是计算机处理起来就很⿇烦,运算顺序往往因表达式的内容⽽定,不具规律性后缀表达式,后缀表达式的特点就是:每⼀运算符都置于其运算对象之后,以上⾯的中缀表达式1+2*3为例⼦,转为后缀表达式就是123*+下⾯先分析怎么把中缀表达式转换为后缀表达式,这⾥我们考虑六种操作符'+'、'-'、'*'、'/'、'('、')',完成中缀转后缀我们需要两个数组,都以栈的⽅式来操作,⼀个数组⽤来存放后缀表达式(char num[100]),⼀个数组⽤来临时存放操作数(char opera[100])(这⾥说临时存放,是因为最后都要⼊栈到后缀表达式数组num中,这个数组就相当于⼀个中转站)1、从左往右扫描中缀表达式(这⾥我们以1*(2+3)为例)2、如果是数字那么将其直接⼊栈到数组num中3、如果是操作数,需要进⼀步判断(1)如果是左括号'('直接⼊栈到数组opera中(2)如果是运算符('+'、'-'、'*'、'/'),先判断数组opera的栈顶的操作数的优先级(如果是空栈那么直接⼊栈到数组opera),如果是左括号那么直接⼊栈到数组opera中,如果栈顶是运算符,且栈顶运算符的优先级⼤于该运算符那么将栈顶的运算符出栈,并⼊栈到数组num中,重复步骤3,如果栈顶运算符优先级⼩于该运算符,那么直接将该运算符⼊栈到opera中(3)如果是右括号')',那么说明在opera数组中⼀定有⼀个左括号与之对应(在你没输错的情况下),那么将opera中的运算符依次出栈,并⼊栈到num中,直到遇到左括号'('(注意左括号不⽤⼊栈到num)4、如果中缀表达式扫描完了,那么将opera中的操作数依次出栈,并⼊栈到num中就可以了,如果没有没有扫描完重复1-3步上⾯就是中缀表达式转后缀表达式的步骤了,下⾯⽤图来直观的了解⼀下这个过程需要注意的是:opera中操作数,越靠近栈顶,优先级越⾼,下⾯附上实现代码View Code后缀表达式的计算完成了中缀表达式转后缀表达式,接下来就是后缀表达式的计算了,后缀表达式的计算⽐中缀转后缀要稍微简单⼀点,只需要对我们转换好的后缀表达式从左往右依次扫描,并依次⼊栈就⾏了,意思是只需要⽤⼀个数组(double num[100])就OK了需要考虑的情况如下1、如果是数字,那么直接⼊栈到num中2、如果是运算符,将栈顶的两个数字出栈(因为我们考虑的运算符加、减、乘、除都是双⽬运算符,只需要两个操作数),出栈后对两个数字进⾏相应的运算,并将运算结果⼊栈3、直到遇到'\0'下⾯⽤⼏张图,来直观了解下这个过程,以上⾯转换好的后缀表达式"123+*"为例(这⾥⽤ss来存储后缀表达式,num来存储计算结果,注意不要与上⾯图中num搞混淆了)(注意:这⾥将计算结果5⼊栈后,栈顶从之前的[3]变成[2])到这⾥后缀表达式的计算就结束了,下⾯附上实现代码[](javascript:void(0)1 #include <stdio.h>2 #include <stdlib.h>34 #define MAX 10056 void JudgeFopen_s(errno_t err); /* 判断⽂件打开是否成功 */7 void ReadFile(FILE *fp, char *ss); /* 读取⽂件内容 */8 double TransformCtoD(char ch); /* 将char类型数组的每⼀个元素转换为double */9 void CalculateAndPush(double *num, int *i, int *j, char mm); /* 计算结果并⼊栈 */1011 int main()12 {13 FILE *fp;14 errno_t err;1516 char ss[MAX]; /* 存储逆波兰表达式 */17 int i = 0;18 int j = 0;19 double num[MAX]; /* 栈 */2021 err = fopen_s(&fp, "E:\\ww.txt", "r");2223 JudgeFopen_s(err); /* 判断⽂件打开是否成功 */24 ReadFile(fp, ss); /* 读取⽂件内容,存储到ss中*/2526 while (ss[i] != '\0')27 {28 if (ss[i] >= '0' && ss[i] <= '9') /* 如果是数字 */29 {30 /* 因为num是char类型的,需要转换为double类型⽅便计算 */31 num[j] = TransformCtoD(ss[i]); /* 将数字存储到栈中 */32 j++;33 i++;34 }35 else if (ss[i] == '+' || ss[i] == '-' || ss[i] == '*' || ss[i] == '/')36 {37 CalculateAndPush(num, &i, &j, ss[i]); /* 计算结果并⼊栈 */38 }39 else if (ss[i] == '\n') /* 如果是换⾏符,结束循环*/40 {41 break;42 }43 }4445 printf("%lf", num[0]);4647 return 0;48 }4950 /* Function: 计算结果并⼊栈 */51 void CalculateAndPush(double *num, int *i, int *j, char mm)52 {53 switch (mm)54 {55 case '+':56 {57 num[(*j)-2] = num[(*j)-1] + num[(*j)-2];58 (*j)--;59 (*i)++;60 break;61 }62 case '-':63 {64 num[(*j)-2] = num[(*j)-1] - num[(*j)-2];65 (*j)--;66 (*i)++;67 break;68 }69 case '*':70 {71 num[(*j)-2] = num[(*j)-1] * num[(*j)-2];72 (*j)--;73 (*i)++;74 break;75 }76 case '/':77 {78 num[(*j)-2] = num[(*j)-1] / num[(*j)-2];79 (*j)--;80 (*i)++;81 break;82 }83 default:84 {85 exit(0);86 }87 }88 }89 /* Function: 判断⽂件打开是否成功 */90 void JudgeFopen_s(errno_t err)91 {92 if (err != 0)93 {94 printf("⽂件打开失败\n");95 system("pause");96 exit(0);97 }98 }99100 /* Function: 读取⽂件内容*/101 void ReadFile(FILE *fp, char *ss)102 {103 int i = 0;104105 while (!feof(fp))106 {107 fscanf_s(fp, "%c", &ss[i]);108 i++;109 }110 ss[i-1] = '\0';111 }112113 /* Function: 将char类型数组的每⼀个元素转换为double */ 114 double TransformCtoD(char ch)115 {116 return (double)(ch - '0');117 }。

中缀转后缀数据结构

中缀转后缀数据结构

将中缀表达式转换为后缀表达式需要使用栈数据结构。

具体步骤如下:1. 读入中缀表达式,遇到数字时将其输出,遇到左括号时将其压入栈中。

2. 读入运算符,如果该运算符优先级高于栈顶运算符的优先级,则将栈顶元素弹出并输出,直到遇到优先级更高的运算符或遇到右括号为止。

3. 如果该运算符优先级等于栈顶运算符的优先级,则将该运算符压入栈中。

4. 如果该运算符优先级低于栈顶运算符的优先级,则忽略该运算符。

5. 重复上述步骤,直到读完整个中缀表达式。

6. 将栈中的元素依次弹出并输出,即为转换后的后缀表达式。

例如,对于中缀表达式a + b * c + (d * e + f) * g,其转换成后缀表达式的步骤如下:1. 读到a,直接输出。

2. 读到+,将+ 压入栈中。

3. 读到b,直接输出。

4. 读到*,将* 压入栈中。

5. 读到c,直接输出。

6. 读到+,将栈顶的* 弹出并输出,然后将+ 压入栈中。

7. 读到(,将( 压入栈中。

8. 读到d,直接输出。

9. 读到*,将* 压入栈中。

10. 读到e,直接输出。

11. 读到+,将栈顶的* 弹出并输出,然后将+ 压入栈中。

12. 读到f,直接输出。

13. 读到),将栈顶的+ 弹出并输出,直到遇到左括号为止。

此时右括号")" 的优先级最高,所以直接将其弹出并输出。

然后继续弹出并输出左括号"(" 前遇到的运算符和操作数,直到遇到右括号为止。

此时右括号")" 前已经没有运算符和操作数了,所以直接将其弹出并输出。

14. 读到*,将* 压入栈中。

15. 读到g,直接输出。

16. 中缀表达式已经读完,将栈中的元素依次弹出并输出,得到后缀表达式a b * c + d * e + f * g + 。

中缀表达式转后缀表达式

中缀表达式转后缀表达式

中缀表达式转后缀表达式 先看⼏个中缀表达式和它们对应的后缀表达式的例⼦ 可以看到操作数a, b, c 在中缀表达式中的顺序和在后缀表达式中的顺序是⼀致的,但操作符的顺序可能不⼀致,因为在中缀表达式中操作符有优先级,括号也能改变运算的优先级,这些都要在后缀表达式中体现出来,后缀表达式中没有括号。

那怎么转化呢? 1,创建⼀个变量,初始化为空的字符串,来表⽰要完成的后缀表达式,创建⼀个字符栈,⽤来存储操作符 2,从左向右依次扫描中缀表达式, 遇到操作数,直接加到后缀表达式的后⾯,因为,在中缀表达式和后缀表达式中,操作数的顺序是⼀样的, 遇到操作符,要先存起来,存到栈中,因为操作符有优先级,它要和后⾯的操作符⽐较优先级,然后才能决定把它放到什么哪个位置。

如果栈为空,直接把操作符放⼊栈中 如果栈不为空,⽐较优先级。

如果遇到的操作符⽐栈顶中的操作符优先级⾼,把遇到的操作符放⼊栈中。

如果遇到的操作符和栈顶操作符的优先级相等,这要考虑操作符的结合性,它是从左到右结合,还是从右到左结合。

从左到右接合,就是操作数属于它前⾯的操作符⽽不是它后⾯操作符。

+, - , * , / 就是从左向右结合,⽐如a-b+c中的b 是-的操作数,⽽不是+的操作数,整个表达式,也是从左向右计算的。

从右向左结合,操作数属于它前⾯的操作符⽽不是它后⾯操作符,⽐如阶乘。

a ^ b ^ c, b是第⼆个^的操作数,⽽不是第⼀个^的操作数,整个表达式也是从右向左计算,a ^ (b ^ c)。

如果从左向右接合,那就弹栈,把操作符放到后缀表达式中,如果从右向左结合,则把遇到的操作符放⼊栈中(和优先级⾼的情况⼀致) 如果遇到的操作符⽐栈顶中的操作符优先级低,那就弹栈,把操作符放到后缀表达式中 遇到(,放到字符栈,因为要等到)才能知道怎么操作。

遇到),依次从字栈中弹栈,放到后缀表达式中,直到遇到(, 遇到(, 要把它弹栈,然后舍弃掉。

3,循环完毕,如果字符栈中还有操作符,依次弹栈放到后缀表达式中,最终栈为空,得到完整的后缀表达式。

python数据结构之中缀表达式转后缀表达式(栈的应用)

python数据结构之中缀表达式转后缀表达式(栈的应用)

python数据结构之中缀表达式转后缀表达式(栈的应⽤)1.设计的算法流程 ⾸先将⼀个中缀表达式从左到右的扫描,设计括号和操作符的优先级。

然后遍历切⽚后的中缀表达式。

遇到操作数就添加到后缀表达式的列表中去,遇到操作符就压⼊栈要求必须是操作符优先级⼤的在上⾯, 遇到左括号就标记,然后呢再就按照⽆括号的⽅法遍历,直到遇到右括号,然后再将操作符弹出直⾄左括号,然后再接着遍历,遍历到最后之后,将 栈⾥⾯的操作符弹出即可,完成中缀转后缀的操作。

具体实现如下from Stack import *def infixToPostfix(infixexpr):prec={}prec['*']=3prec['/']=3prec['+']=2prec['-']=2prec['(']=1opStack=Stack()postfixlist,tokenlist=[],[]for mark in range(len(infixexpr)):tokenlist.append(infixexpr[mark])print(tokenlist)for token in tokenlist:if token in'ABCDEFGHIJKLMNOPQRSTUVWXYZ'or token in'0123456789':postfixlist.append(token)elif token=='(':opStack.push(token)elif token==')':topToken=opStack.pop()while topToken!="(":postfixlist.append(topToken)topToken=opStack.pop()else:while (not opStack.isempity()) and (prec[opStack.get_stack()]>=prec[token]):postfixlist.append(opStack.pop())opStack.push(token)while not opStack.isempity():postfixlist.append(opStack.pop())return"".join(postfixlist)if__name__ == '__main__':n='A+B*C'print(infixToPostfix(n))这⾥将栈的get_stack⽅法修改了⼀下,变成拿到栈顶的数据。

中缀表达式转换为后缀表达式

中缀表达式转换为后缀表达式

中缀表达式转换为后缀表达式中缀表达式转换成后缀表达式 1、概述 可以看到,后缀表达式适合计算式进⾏运算,但是⼈却不太容易写出来,尤其是表达式很长得情况下,因此在开发中,需要将中缀表达式转成后缀表达式。

2、具体步骤1.初始化两个栈:运算符栈s1和储存中间结果的栈s2;2.从左⾄右扫描中缀表达式;3.遇到操作数时,将其压s2;4.遇到运算符时,⽐较其与s1栈顶运算符的优先级: (1)如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符⼊栈; (2)否则,若优先级⽐栈顶运算符的⾼,也将运算符压⼊s1; (3)否则,将s1栈顶的运算符弹出并压⼊到s2中,再次转到(4.1)与s1中新的栈顶运算符相⽐较;5.遇到括号时: (1)如果是左括号"(",则直接压⼊s1 (2)如果是右括号")",则依次弹出s1栈顶的运算符,并压⼊s2,直到遇到左括号为⽌,此时将这⼀对括号丢弃6.重复步骤2⾄5,直到表达式的最右边7.将s1中剩余的运算符依次弹出并压⼊s28.依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式 3、案例 将中缀表达式 "1+((2+3)*4)-5" 转换为后缀表达式的过程如下: 结果为:"1 2 3 + 4 * 5 - " 4、思路分析⽰意图 5、代码实现1import java.util.ArrayList;2import java.util.List;3import java.util.Stack;45/**6 * 把中缀表达式转成后缀表达式7 *8*/9public class ToSuffixExpression {1011public static void main(String[] args) {12// 完成⼀个中缀表达式转成后缀表达式13// 说明14// 1. 1+((2+3)*4)-5 => 转成 123 + 4 * + 5-15// 2. 因为对 str进⾏操作不⽅便,先将中缀表达式存⼊ list16// 3.将得到的中缀表达式对应的 list转成 =>后缀表达式对应的list17// 即[1,+,(,(,2,+,3,),*,4,),-,5] => [1,2,3,+,4,*,+,5,-]1819 String expression = "1+((2+3)*4)-5";20 List<String> list = toInfixExpressionList(expression);21 System.out.println("中缀表达式对应的list="+list);22 List<String> list2 = parseSuffixExpressionList(list);23 System.out.println("后缀表达式对应的list="+list2);24 }2526//⽅法:将得到的中缀表达式对应的 list转成 =>后缀表达式对应的list27public static List<String> parseSuffixExpressionList(List<String> ls) {28//定义两个栈29 Stack<String> s1 = new Stack<String>(); // 符号栈3031//说明:因为 s2这个栈,在整个转换过程中,没有pop操作,后⾯还需要逆序输出 32//所以,把 s2 这个栈换成 List<String> 即可33//Stack<String> s2 = new Stack<String>(); // 存储中间结果的栈34 List<String> s2 = new ArrayList<String>(); //存储中间结果的list3536//遍历 ls37for(String item : ls) {38//如果是⼀个栈,就加⼊到s239if(item.matches("\\d+")) {40 s2.add(item);41 } else if (item.equals("(")) {42 s1.push(item);43 } else if (item.equals(")")) {44// 如果是右括号,则依次弹出s1栈顶的运算符,并压⼊ s2,知道遇到左括号为⽌,此时将这⼀对括号丢弃4546while(!s1.peek().equals("(")) {47 s2.add(s1.pop());48 }49 s1.pop(); // 将左括号弹出,消除⼩括号50 } else {51// 当 item 的优先级⼩于或等于栈顶运算符,将s1栈顶的运算符弹出并压⼊s2中,再次转到4.1与s1中新的栈顶运算符相⽐较 52//问题:缺少⽐较优先级⾼低的⽅法53while(s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {54 s2.add(s1.pop());55 }56//还需要将 item 压⼊栈中57 s1.push(item);58 }59 }6061//将s1中剩余的运算符依次弹出加⼊s262while(s1.size()!=0) {63 s2.add(s1.pop());64 }6566return s2; //因为存放到list中,因此,按顺序输出就是对应的后缀表达式对应的 list67 }686970// ⽅法:将中缀表达式转成对应的 list71public static List<String> toInfixExpressionList(String s) {72// 定义⼀个 list,存放中缀表达式对应的内容73 List<String> ls = new ArrayList<String>();74int i = 0; // 指针,⽤于遍历中缀表达式字符串75 String str; // 做对多位数的拼接⼯作76char c; // 每遍历到⼀个字符,就放⼊到 c7778do {79// 如果c是⼀个⾮数字,就需要加⼊到 ls80if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) {81 ls.add("" + c);82 i++; // i后移83 } else { // 如果是数字,考虑多位数问题84 str = ""; // 将 str置空85while (i < s.length() && (c = s.charAt(i)) >= 48 && (c = s.charAt(i)) <= 57) {86 str += c; // 拼接87 i++;88 }89 ls.add(str);90 }9192 } while (i < s.length());93return ls; // 返回94 }95 }9697/**98 * 可以返回⼀个运算符的对应的优先级99 *100*/101public class Operation {102private static int ADD = 1;103private static int SUB = 1;104private static int MUL = 2;105private static int DIV = 2;106107// 写⼀个⽅法,返回对应的优先级数字108public static int getValue(String operation) { 109int result = 0;110switch(operation) {111case "+":112 result = ADD;113break;114case "-":115 result = SUB;116break;117case "*":118 result = MUL;119break;120case "/":121 result = DIV;122break;123default:124 System.out.println("不存在该运算符"); 125break;126 }127return result;128 }129 }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
printf("No enough memory!");
return NULL;
}
S->Next = NULL;
MakeEmpty(S);
return S;
}
//清空栈
void MakeEmpty(Stack S)
{
if(S == NULL)
{
printf("Use CreateStack First!");
{
return 3;
}
else
{
fprintf(stderr,"Input char is invalid!\n");
return -1;
}
}
/****************************************************************
*判断一个字符是不是运算符
*如果是合法的运算符+、-、*、/、(、)则返回0,否则返回1
}
else
{
while(!IsEmpty(S))
{
Pop(S);
}
}
}
//进栈
void Push(ElementType X,Stack S)
{
PtrToNode Tmp;
Tmp = malloc(sizeof(struct Node));
if(Tmp != NULL)
{
Tmp->Element = X;
遇到a,直接输出:
遇到+,此时栈为空,入栈:
遇到b,直接输出:
遇到*,优先级大于栈顶符号优先级,入栈:
遇到c,输出:
遇到+,目前站内的*与+优先级都大于或等于它,因此将栈内的*,+依次弹出并且输出,并且将遇到的这个+入栈:
遇到(,将其入栈:
遇到d,直接输出:
遇到*,由于*的优先级高于处在栈中的(,因此*入栈:
int GetPrecedence(char c,int flag)
{
if(c=='+' || c=='-')
{
return 1;
}
else if(c=='*' || c=='/')
{
return 2;
}
else if(c=='(' && flag==0)
{
return 0;
}
else if(c=='(' && flag==1)
4.遇到右括号,执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出;
5.遇到其他运算符'+''-''*''/'时,弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈;
6.最终将栈中的元素依次出栈,输出。
经过上面的步骤,得到的输出既是转换得到的后缀表达式。
举例:a+b*c+(d*e+f)*g ---------> abc*+de*f+g*+
Tmp->Next = S->Next;
S->Next = Tmp;
}
else
{
printf("Out of space!");
}
}
//出栈
void Pop(Stack S)
我们在数学中常见的计算式,例如2+(3*4)叫做中缀表达式。表达式中涉及到了多个运算符,而运算符之间是有优先级的。计算机在计算并且处理这种表达式时,需要将中缀表达式转换成后缀表达式,然后再进行计算。
中缀表达式转后缀表达式遵循以下原则:
1.遇到操作数,直接输出;
2.栈为空时,遇到运算符,入栈;
3.遇到左括号,将其入栈;
PtrToNode Next;
};
int IsEmpty(Stack S);
Stack CreateStack();
void DisposeStack(Stack S);
void MakeEmpty(Stack S);
void Push(ElementType X,Stack S);
ElementType Top(Stack S);
void Pop(Stack S);
//判断栈是否为空
int IsEmpty(Stack S)
{
return S->Next == NULL;
}
//创建链栈
Stack CreateStack()
{
Stack S = malloc(sizeof(struct Node));
if(S == NULL)
{
*这里只处理+、-、*、/、(、)这些符号。
*需要注意的是:如果(在栈中,它的优先级是最低的,不在栈中则是最高的
*@param c:需要判断的字符
*@param flag:字符是否在栈中,0表示在栈中,1表示不在栈中
*****************************************************************/
{
return 1;
}
}
/****************************************************************
*完整的代码如下:
****************************************************************/
遇到e,直接输出:
遇到+,栈顶的*优先级高于+,但是栈内的(低于+,将*出栈输出,+入栈:
遇到f,直接输出:
遇到),弹出栈顶元素并且输出,直到弹出(才结束,在这里也就是弹出+输出,弹出(不输出:
遇到*,优先级高于栈顶+,将*入栈:
遇到g,直接输出:
此时已经没有新的字符了,依次出栈并输出操作直到栈为空:
#include <stdio.h>
#include <stdlib.h>
#define ElementType char
typedef struct Node *PtrToNode;
typedef PtrToNode Stack;
typedef struct Node
{
ElementType Element;
****************************************************************/
int IsOperator(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')')
{
return 0;
}
else
明白了这个过程,现在就需要用代码实现了。对于各种运算符的优先级,可以使用整数来表示运算符的级别。可以定义一个函数来返回各种符号的优先级数字:
/*****************************************************************
*根据字符该字符是否在栈中,返回该字符的优先级。
相关文档
最新文档