中序表达式 (a+b)*(c+d)
后续表达式 ab+cd+*
前序表达式 *+ab+cd
说明
平常所使用的运算式,主要是将运算元放在运算子的两旁,例如a+b/d这样的式子,这称之为中序(Infix)表示式,对于人类来说,这样的式子很容易理 解,但由于电脑执行指令时是有顺序的,遇到中序表示式时,无法直接进行运算,而必须进一步判断运算的先后顺序,所以必须将中序表示式转换为另一种表示方法(前序,后序)。
后序:
以ab+cd+*为例,从左至右,先取出两个操作数a,b和一个操作符+,
计算(a+b)记为A,将结果A返回字符串中,即Acd+*,再连续取出A,c,d,直到取到一个运算符+,将与运算符最近的两个c,d进行计算,即(c+d)记为B, 将B返回字符串,
即AB*,取出A,B,操作符,即A乘B
前序:
*+ab+cd 类似于后序,但是是从右至左操作
中序转前序步骤
一,从字符串(从左至右)中取出一个字符
1,如果是操作数,则直接输出
2,如果是“(”直接压入栈中
3,如果是运算符但不是‘(’,‘)’,则不断进行以下处理
(1)如果栈为空,则运算符入栈
(2)如果栈顶为‘(’则此运算符进栈
(3)如果此运算符与栈顶的优先级相同或者更高,则入栈
(4)如果前三个都不满足,则运算符连续出栈,直到满足上面三个之一,然后该运算符进栈
(5)如果为‘)’,运算符连续出栈,直到遇到‘(’,
将‘(’出栈丢之
中序转前序
一,从字符串(从右至左)中取出一个字符(或者先将字符串反转,就从左至右,对结果再反转即最终结果)
1,如果是操作数,则直接输出
2,如果是“)”直接压入栈中
3,如果是运算符但不是‘(’,‘)’,则不断进行以下处理
(1)如果栈为空,则运算符入栈
(2)如果栈顶为‘)’则此运算符进栈
(3)如果此运算符与栈顶的优先级相同或者更高,则入栈
(4)如果前三个都不满足,则运算符连续出栈,直到满足上面三个之一,然后该运算符进栈
(5)如果为‘(’,运算符连续出栈,直到遇到‘)’,
将‘)’出栈丢之
例子(中转后)
如(a+b)*(c+d)
1,取出‘(’,入栈 , 此时栈为‘(’
2,取出a,直接输出,此时输出为a
3,取出+,满足(2),入栈,此时栈为‘(+’
4,取出b,直接输出,此时输出为ab
5,取出‘)’,满足(5),运算符连续出栈,并将‘)’出栈丢之,+号出栈,此时输出为ab+,栈为空
6,取出*,满足(1),运算符入栈
7,取出’(‘,满足2,入栈,此时栈为*(
8,取出c,直接输出,此时输出为ab+c
9,取出+,满足(2)进栈,此时栈为*(+
10,取出d,直接输出,此时输出ab+cd
11,取出‘)’,满足(5),+出栈,(出栈丢之,此时输出ab+cd+,栈为*
12,乘号出栈,ab+cd+*
C代码(中转后)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int zhong_z_hou(char *);//中转后
int priority(char);//优先级判断
int main()
{
char input[80];
printf("请输入一个中序式:");
scanf("%s", input);
zhong_z_hou(input);
system("pause");
return 0;
}
int zhong_z_hou(char *arr)
{
char stack[80] = { '\0' };
int i = 0;//字符串索引
int top = 0; //栈顶
char op;
while (1)
{
op = arr[i];
switch (op)
{
case '\0': //遇到结束符,打印
while (top > 0)
{
printf("%c", stack[top]);
top--;
}
printf("\n");
return 0;
case '(':
if (top < sizeof(stack) / sizeof(char))
{
top++;
stack[top] = op;
}
break;
case '+':
case '-':
case '*':
case '/':
if(priority(op) < priority(stack[top]))
{
printf("%c", stack[top]);
top--;
}
if(top<sizeof(stack)/sizeof(char))
{
top++;
stack[top] = op;
}
break;
case ')':
while (stack[top] != '(')
{
printf("%c", stack[top]);
top--;
}
top--; //丢弃'('
break;
default: //运算符直接打印
printf("%c", op);
break;
}
i++;
}
}
int priority(char c)
{
int p = 0;
if (c == '+' || c == '-')
{
p = 1;
}
if (c == '*' || c == '/')
{
p = 2;
}
return p;
}
python代码(中转前)
# -*- coding: utf-8 -*-
"""
Created on Thu Nov 16 19:44:06 2017
@author: yangwenbin
"""
#中序转前序
def zhong_z_qian(arr):
stack=['\0']*80
save_qian=[] #存放输出的字符
top=0
for i in range(len(arr)-1,-2,-1):
if i==-1:
while top >0:
#print(stack[top],end='')
save_qian.append(stack[top])
stack[top]='\0'
top-=1
#stack[top]='\0'
#break
op=arr[i]
if op==')':
top+=1
stack[top]=op
pass
elif op=='+' or op=='-' or op=='*' or op=='/':
while pre(op)<pre(stack[top]):
#print(stack[top],end='')
save_qian.append(stack[top])
stack[top]='\0'
top-=1
pass
if top<len(stack):
top+=1
stack[top]=op
pass
pass
elif op=='(':
while stack[top]!=')':
#print(stack[top],end='')
save_qian.append(stack[top])
stack[top]='\0'
top-=1
pass
stack[top]='\0'
top-=1
pass
else:
#print(op,end='')
save_qian.append(op)
pass
pass
return save_qian
pass
def pre(c):
p=0
if c=='+' or c=='-':
p=1
pass
if c=='*' or c=='/':
p=2
pass
return p
if __name__=="__main__":
print("请输入一个中序式:")
Input=input()
a=zhong_z_qian(Input)
b=list(reversed(a))#翻转列表
print(''.join(b))#列表转字符串