基本介紹
- 中文名:前綴表達式
- 外文名:Polish notation
- 例如:- 1 + 2 3
- 紀念:Jan Lukasiewicz
- 轉換算法:構造一個運算符棧
- 運算符:直接入棧
- 作用:簡化複雜運算為出棧入棧兩種運算
基本釋義
注意事項
運算優勢
求值方法
表達對照
轉換算法
實例分析
中綴表達式 | 前綴表達式 | (棧尾)運算符棧(棧頂) | 說明 |
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 | 空 | 逆綴輸出字元串 |
符號處理
編程轉換
#include<stdio.h>#include<stdlib.h>#include<conio.h>#include<math.h>#include<string.h>#define MaxSize 99char 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);}
公式轉換
vara:array[1..1000] of string;s:string;i,j,k,l,v:longint;beginreadln(s);j:=0; l:=length(s);for i:=1 to l dobeginif not(s[i]in['+','-','*','/']) thenbeginj:=j+1;a[j]:=s[i];endelsebeginif (j>1)and(s[i]in['/'])and(s[i-1]in['*','/']) thena[j]:='('+a[j]+')';j:=j-1;a[j]:=a[j]+s[i]+a[j+1];if (i<l)and(s[i]in['+','-']) thenbegink:=i;v:=0;repeatk:=k+1;if s[k]in['+','-','*','/'] then v:=v-1else 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.