数据结构-前缀、中缀、后缀表达式
2016-07-27 11:29
232 查看
<span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px; background-color: rgb(255, 255, 255);">举例:</span>(3 + 4) × 5 - 6 就是中缀表达式- × + 3 4 5 6 前缀表达式3 4 + 5 × 6 - 后缀表达式中缀表达式(中缀记法)中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单。前缀表达式(前缀记法、波兰式)前缀表达式的运算符位于操作数之前。前缀表达式的计算机求值:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。例如前缀表达式“- × + 3 4 5 6”:(1) 从右至左扫描,将6、5、4、3压入堆栈;(2) 遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;(3) 接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;(4) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。可以看出,用计算机计算前缀表达式的值是很容易的。将中缀表达式转换为前缀表达式:遵循以下步骤:(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;(2) 从右至左扫描中缀表达式;(3) 遇到操作数时,将其压入S2;(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:(4-1) 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;(4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;(5) 遇到括号时:(5-1) 如果是右括号“)”,则直接压入S1;(5-2) 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;(6) 重复步骤(2)至(5),直到表达式的最左边;(7) 将S1中剩余的运算符依次弹出并压入S2;(8) 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。例如,将中缀表达式“1+((2+3)×4)-5”转换为前缀表达式的过程如下:
扫描到的元素 | S2(栈底->栈顶) | S1 (栈底->栈顶) | 说明 |
5 | 5 | 空 | 数字,直接入栈 |
- | 5 | - | S1为空,运算符直接入栈 |
) | 5 | - ) | 右括号直接入栈 |
4 | 5 4 | - ) | 数字直接入栈 |
× | 5 4 | - ) × | S1栈顶是右括号,直接入栈 |
) | 5 4 | - ) × ) | 右括号直接入栈 |
3 | 5 4 3 | - ) × ) | 数字 |
+ | 5 4 3 | - ) × ) + | S1栈顶是右括号,直接入栈 |
2 | 5 4 3 2 | - ) × ) + | 数字 |
( | 5 4 3 2 + | - ) × | 左括号,弹出运算符直至遇到右括号 |
( | 5 4 3 2 + × | - | 同上 |
+ | 5 4 3 2 + × | - + | 优先级与-相同,入栈 |
1 | 5 4 3 2 + × 1 | - + | 数字 |
到达最左端 | 5 4 3 2 + × 1 + - | 空 | S1中剩余的运算符 |
扫描到的元素 | S2(栈底->栈顶) | S1 (栈底->栈顶) | 说明 |
1 | 1 | 空 | 数字,直接入栈 |
+ | 1 | + | S1为空,运算符直接入栈 |
( | 1 | + ( | 左括号,直接入栈 |
( | 1 | + ( ( | 同上 |
2 | 1 2 | + ( ( | 数字 |
+ | 1 2 | + ( ( + | S1栈顶为左括号,运算符直接入栈 |
3 | 1 2 3 | + ( ( + | 数字 |
) | 1 2 3 + | + ( | 右括号,弹出运算符直至遇到左括号 |
× | 1 2 3 + | + ( × | S1栈顶为左括号,运算符直接入栈 |
4 | 1 2 3 + 4 | + ( × | 数字 |
) | 1 2 3 + 4 × | + | 右括号,弹出运算符直至遇到左括号 |
- | 1 2 3 + 4 × + | - | -与+优先级相同,因此弹出+,再压入- |
5 | 1 2 3 + 4 × + 5 | - | 数字 |
到达最右端 | 1 2 3 + 4 × + 5 - | 空 | S1中剩余的运算符 |
#include<stdio.h>#include<stdlib.h>#include<string.h>int judge(char a,char b){if((a=='*'||a=='/')&&(b=='+'||b=='-'))return 1;else if((a=='+'||a=='-')&&(b=='*'||b=='/'))return -1;else if((a=='+'||a=='-')&&(b=='+'||b=='-'))return 0;else if((a=='*'||a=='/')&&(b=='*'||b=='/'))return 0;}void houzhui(char a[]){char c2[1005],c1[1005];int t1,t2,i;t1=t2=-1;for(i=0; a[i]!='#'; i++){if(a[i]!='*'&&a[i]!='-'&&a[i]!='+'&&a[i]!='/'&&a[i]!='('&&a[i]!=')'){c2[++t2]=a[i];}else{if(t1==-1||c1[t1]=='('||a[i]=='('){c1[++t1]=a[i];// printf("%c",c1[t1]);}else if(a[i]==')'){//t1--;while(c1[t1]!='('){c2[++t2]=c1[t1--];}t1--;}else{if(judge(a[i],c1[t1])==1)c1[++t1]=a[i];else{c2[++t2]=c1[t1--];i--;}}}}while(t1!=-1){c2[++t2]=c1[t1--];}for(int i=0; i<=t2; i++)printf("%c",c2[i]);printf("\n");}void zhongzhui(char a[]){char c2[1005],c1[1005];//c2Ã¥Â��c1Ã¥Â���符int t1,t2,i;t1=t2=-1;for(i=0; a[i]!='#'; i++){if(a[i]!='('&&a[i]!=')'){c2[++t2]=a[i];}}for(int i=0; i<=t2; i++)printf("%c",c2[i]);printf("\n");}void qianzhui(char a[]){char c2[1005],c1[1005];//c2Ã¥Â��c1Ã¥Â���符int t1,t2,i;t1=t2=-1;int l=strlen(a);for(i=l-2; i>=0; i--){if(a[i]!='*'&&a[i]!='-'&&a[i]!='+'&&a[i]!='/'&&a[i]!='('&&a[i]!=')'){c2[++t2]=a[i];}else{if(t1==-1||c1[t1]==')'||a[i]==')'){c1[++t1]=a[i];// printf("%c",c1[t1]);}else if(a[i]=='('){//t1--;while(c1[t1]!=')'){c2[++t2]=c1[t1--];}t1--;}else{if(judge(a[i],c1[t1])==-1){c2[++t2]=c1[t1--];i++;}elsec1[++t1]=a[i];}}}while(t1!=-1){c2[++t2]=c1[t1--];}for(int i=t2; i>=0; i--)printf("%c",c2[i]);printf("\n");}int main(){char a[1005];scanf("%s",a);qianzhui(a);zhongzhui(a);houzhui(a);}
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)