前缀表达式

前缀表达式就是前序表达式

前缀表达式就是 前序表达式

编辑本段什么是前缀表达式

前缀表达式就是不含括号的 算术表达式,而且它是将 运算符写在前面, 操作数写在后面的表达式,为纪念其发明者波兰数学家Jan Lukasiewicz也称为“波兰式”。例如,- 1 + 2 3,它等价于1-(2+3)。

编辑本段前缀表达式如何求值

对于一个前缀表达式的求值而言,首先要从右至左扫描表达式,从右边第一个字符开始判断,如果当前字符是数字则一直到数字串的末尾再记录下来,如果是 运算符,则将右边离得最近的两个“数字串”作相应的运算,以此作为一个新的“数字串”并记录下来。一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。例如,前缀表达式“- 1 + 2 3“的求值,扫描到3时,记录下这个数字串,扫描到2时,记录下这个数字串,当扫描到+时,将+右移做相邻两数字串的 运算符,记为2+3,结果为5,记录下这个新数字串,并继续向左扫描,扫描到1时,记录下这个数字串,扫描到-时,将-右移做相邻两数字串的运算符,记为1-5,结果为-4,所以表达式的值为-4。

编辑本段前缀表达式有什么用处

前缀表达式是一种十分有用的表达式,它将中缀表达式转换为可以依靠简单的操作就能得到运算结果的表达式。例如,(a+b)*(c+d)转换为*,+,a,b,+,c,d。它的优势在于只用两种简单的操作,入栈和 出栈就可以解决任何中缀表达式的运算。其运算方式为:如果当前字符(或字符串)为数字或 变量,则压入栈内;如果是 运算符,则将栈顶两个元素弹出栈外并作相应运算,再将结果压入栈内。当前缀表达式扫描结束时,栈里的就是中缀表达式运算的最终结果。

编辑本段中缀表达式转换为前缀表达式的一些例子

a+b ---> +,a,b 
a+(b-c) ---> +,a,-,b,c 
a+(b-c)*d ---> +,a,*,-,b,c,d 
a=1+3 ---> =,a,+,1,3

编辑本段中缀表达式转换为前缀表达式的一般算法

(1) 首先构造一个运算符栈(也可放置括号),运算符(以括号分界点)在栈内遵循越往栈顶优先级不降低的原则进行排列。 
(2)从右至左扫描中缀表达式,从右边第一个字符开始判断: 
如果当前 字符是数字,则分析到数字串的结尾并将数字串直接输出。 
如果是运算符,则比较优先级。如果当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),则将运算符直接入栈;否则将栈顶运算符 出栈并输出,直到当前运算符的优先级大于等于栈顶运算符的优先级(当栈顶是括号时,直接入栈),再将当前运算符入栈。 
如果是括号,则根据括号的方向进行处理。如果是右括号,则直接入栈;否则,遇左括号前将所有的运算符全部 出栈并输出,遇左括号后将左右的两括号一起删除。 
(3) 重复上述操作(2)直至扫描结束,将栈内剩余运算符全部 出栈并输出,再逆缀输出字符串。中缀表达式也就转换为前缀表达式了。

编辑本段实例分析

将中缀表达式“1+((2+3)*4)-5”转换为前缀表达式。 
中缀表达式
前缀表达式
(栈顶)运算符栈(栈尾)
说明 
5
5
5,是数字串直接输出
-
5
-
-,栈内无运算符,直接入栈
5
-)
),直接入栈
4
5 4
-)
4,是数字串直接输出
*
5 4
-)*
*,栈顶是括号,直接入栈
)
5 4
- ) * )
),直接入栈 
3
5 4 3
- ) * )
3,是数字串直接输出
+
5 4 3
- ) * ) +
+,栈顶是括号,直接入栈
2
5 4 3 2
- ) * )+
2,是数字串直接输出
(
5 4 3 2+
- ) *
(,参考① 
(
5 4 3 2+*
-
(,参考①
+
5 4 3 2+*
-+
+,优先级大于等于栈顶运算符,直接入栈
1
5 4 3 2+*1
-+
1,是数字串直接输出
5 4 3 2+*1+-
扫描结束,将栈内剩余运算符全部出栈并输出
- + 1 * + 2 3 4 5
逆缀输出字符串

编辑本段各运算符及符号优先级

):直接入栈 
(:遇)前,将运算符全部出栈并输出;遇)后,将两括号一起删除①
+、-:1 
*、/、%:2 
^:3

编辑本段用编程实现中缀表达式向前缀表达式的转换

#include< stdio.h>
#include< conio.h>
#include< math.h>
#include< string.h>
#define MaxSize 99
char calc[MaxSize],expr[MaxSize];
int i,t;
struct
{
char data[MaxSize];
int top;
}Sym;
struct
{
double data[MaxSize];
int top;
}Num;
double ston(char x[],int *p)
{
int j=*p-1,i;
double n=0,m=0;
while(x[j]>='0'&&x[j]<='9')
{
j--;
}
if(x[j]!='.')
{
for(i=j+1;i<=*p;i++)
{
n=10*n+(x[i]-'0');
}
}
else
{
for(i=j+1;i<=*p;i++)
{
m=m+pow(0.1,i-j)*(x[i]-'0');
}
if(x[j]=='.')
{
*p=--j;
while(x[j]>='0'&&x[j]<='9')
{
j--;
}
for(i=j+1;i<=*p;i++)
{
n=10*n+(x[i]-'0');
}
}
}
*p=j;
if(x[*p]=='-') return(-(n+m));
return(n+m);
}
void InitStack()
{
Sym.top=Num.top=-1;
}
void SymPush()
{
if(Sym.top<MaxSize-1)
{
Sym.data[++Sym.top]=calc[i--];
}
else
{
printf("Sym栈满\n");
return;
}
}
void SymPop()
{
if(Sym.top>=0)
{
expr[++t]=Sym.data[Sym.top--];
}
else
{
printf("Sym栈空\n");
return;
}
}
void NumPush()
{
if(Num.top<MaxSize-1)
{
Num.data[++Num.top]=ston(expr,&i);
}
else
{
printf("Num栈满\n");
return;
}
}
void NumPop()
{
if(Num.top>=0)
{
if(expr[i]!=' ')
{
switch(expr[i])
{
case '+':Num.data[Num.top-1]=Num.data[Num.top]+Num.data[Num.top-1];break;
case '-':Num.data[Num.top-1]=Num.data[Num.top]-Num.data[Num.top-1];break;
case '*':Num.data[Num.top-1]=Num.data[Num.top]*Num.data[Num.top-1];break;
case '/':Num.data[Num.top-1]=Num.data[Num.top]/Num.data[Num.top-1];break;
case '^':Num.data[Num.top-1]=pow(Num.data[Num.top],Num.data[Num.top-1]);break;
}
Num.top--;
}
}
else
{
printf("Num栈空\n");
return;
}
}
int main(void)
{
char ch;
loop1:
i=0,t=-1;
system("cls");
printf("中缀表达式:");
InitStack(),gets(calc);
while(calc[i]!='\0')
{
i++;
}
while(i>=0)
{
if(calc[i]>='0'&&calc[i]<='9')
{
while((i>=0)&&((calc[i]>='0'&&calc[i]<='9')||(calc[i]=='.')))
{
loop2:
expr[++t]=calc[i--];
}
if((i>=0)&&((i==0&&calc[i]!='(')||(calc[i]=='+'||calc[i]=='-')&&!(calc[i-1]>='0'&&calc[i-1]<='9')&&calc[i-1]!=')')) goto loop2;
expr[++t]=' ';
}
else if(calc[i]==')')
{
SymPush();
}
else if(calc[i]=='(')
{
while(Sym.data[Sym.top]!=')')
{
SymPop();
expr[++t]=' ';
}
Sym.data[Sym.top--]='\0';
i--;
}
else if(calc[i]=='+'||calc[i]=='-')
{
while(Sym.top>=0&&Sym.data[Sym.top]!=')'&&Sym.data[Sym.top]!='+'&&Sym.data[Sym.top]!='-')
{
SymPop();
expr[++t]=' ';
}
SymPush();
}
else if(calc[i]=='*'||calc[i]=='/')
{
while(Sym.top>=0&&Sym.data[Sym.top]=='^')
{
SymPop();
expr[++t]=' ';
}
SymPush();
}
else if(calc[i]=='^')
{
SymPush();
}
else
{
i--;
}
}
while(Sym.top>=0)
{
SymPop();
expr[++t]=' ';
}
expr[++t]=Sym.data[++Sym.top]='\0';
for(i=0;i<=(t-2)/2;i++)
{
ch=expr[i];
expr[i]=expr[(t-2)-i];
expr[(t-2)-i]=ch;
}
printf("前缀表达式:%s\n",expr);
for(i=t-2;i>=0;i--)
{
if((expr[i]>='0'&&expr[i]<='9')||((expr[i]=='+'||expr[i]=='-')&&(expr[i+1]>='0'&&expr[i+1]<='9')))
{
NumPush();
}
else
{
NumPop();
}
}
printf("运算结果为:%g\n",Num.data[0]);
printf("Continue(y/n)?");
ch=getch();
switch(ch)
{
case 'y':{system("cls");goto loop1;}
case 'n':
default :exit(0);
}
getch();
return(0);
}

编辑本段后缀表达式转前缀表达式

var
a:array[1..1000] of string;
s:string;
i,j,k,l,v:longint;
begin
readln(s);
j:=0; l:=length(s);
for i:=1 to l do
begin
if not(s[i]in['+','-','*','/']) then
begin
j:=j+1;
a[j]:=s[i];
end
else
begin
if (j>1)and(s[i]in['/'])and(s[i-1]in['*','/']) then
a[j]:='('+a[j]+')';
j:=j-1;
a[j]:=a[j]+s[i]+a[j+1];
if (i<l)and(s[i]in['+','-']) then
begin
k:=i;
v:=0;
repeat
k:=k+1;
if s[k]in['+','-','*','/'] then v:=v-1
else v:=v+1;
until (k=l)or(v<1);
if (k<l)and(s[k]in['*','/']) then a[j]:='('+a[j]+')';
end;
end;
end;
writeln(a[1]);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值