資料結構——表示式轉換
阿新 • • 發佈:2019-02-08
除去表示式轉換的基本規則,個人認為表示式轉換有以下三個難點:
1、小數沒有辦法表示和輸出;
2、數字本身自帶的負號難以表達和實現;
3、多位數字沒有辦法很好的去表達。
類如PTA 7-1這道題:
輸入格式:
輸入在一行中給出不含空格的中綴表示式,可包含+、-、*、\以及左右括號(),表示式不超過20個字元。
輸出格式:
在一行中輸出轉換後的字尾表示式,要求不同物件(運算數、運算子號)之間以空格分隔,但結尾不得有多餘空格。
輸入樣例:
2+3*(7-4)+8/4
輸出樣例:
2 3 7 4 - * + 8 4 / +
很多人(包括我自己,咳咳)在掌握了基本的轉換規則後,仍然無法解決此題,很多問題就是出現在上面提到的三點,可以拿著三點出幾組資料看看是否能卡死自己的程式碼。
在網上翻閱了很多的此類題的模板,在參考了這篇部落格後表示式轉換模板,精煉出了一套模板,在這裡與大家分享.
AC程式碼(此程式碼通過了PTA的測試資料),程式碼有點長,希望大家耐心看完:
#include <bits/stdc++.h> using namespace std; const int maxn=100; char s[maxn]; int len; bool judge(char c) { return c=='-'||c=='+'; } bool judge1(char c) { return c=='('; } bool compare(char a,char b)//優先順序的比較 { if(a=='(') return 0; if(b=='+'||b=='-') return 1; else { if(a=='*'||a=='/') return 1; else return 0; } } void solve() { char mark[maxn]; int pos=0,flag=0;//flag用來控制中間空格的輸出,主要是多位數字的輸出 for(int i=0;i<len;i++) { if((s[i]>='0'&&s[i]<='9')||s[i]=='.')//若為數字直接輸出,注意小數點的處理 { if(flag) printf(" "); printf("%c",s[i]); flag=0; } else if(judge(s[i])&&(i ? judge1(s[i-1]) : 1 ))//判斷負號是否為本身所有 { if(s[i]=='-') { if(flag) printf(" "); printf("%c",s[i]); flag=0; } } else//其餘字元的按規則處理 { if(pos) { if(s[i]=='(') mark[pos++]=s[i]; else if(s[i]==')')//對於左括號的處理 { while(pos--) { if(mark[pos]=='(') break; printf(" %c",mark[pos]); } } else { while(pos)//對於優先順序規則的處理 { if(compare(mark[pos-1],s[i])) printf(" %c",mark[--pos]);//輸出符號前必然有數字的輸出,所以直接輸出空格即可 else break; } mark[pos++]=s[i]; } } else mark[pos++]=s[i];//如果為空則直接壓入 for(int j=0;j<pos;j++)//判斷是否控制格式,主要是排除(、)對格式控制的影響 { if(mark[j]!='(') { flag=1; break; } } } } while(pos) { printf(" %c",mark[--pos]); } } int main() { scanf("%s",s); len=strlen(s); solve(); return 0; }