洛谷【P1175】表達式的轉換
阿新 • • 發佈:2019-01-17
urn new 數字 put 入棧 stk .html 優先 單調棧
淺談棧:https://www.cnblogs.com/AKMer/p/10278222.html
題目傳送門:https://www.luogu.org/problemnew/show/P1175
中綴表達式轉後綴表達式之後直接模擬即可。平常我們所用的都是中綴表達式,後綴表達式題面已經說的很清楚了。
至於怎麽轉?按照一下幾條規則用單調棧維護運算符模擬即可:
1、如果當前位是數字,則直接輸出
2、如果當前位是左括號,則直接丟棧然後不管
3、如果當前位是運算符,把棧頂優先度不小於當前運算符的全部彈出然後輸出,當前運算符入棧
4、如果是右括號,一直彈棧輸出直到與之匹配的左括號出棧
優先級:括號>乘方>乘除>加減
時間復雜度:\(O(len^2)\)
空間復雜度:\(O(len)\)
代碼如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef pair<int,int> pii; #define ff first #define ss second const int maxn=105; int n1,n2,top,cnt; char s[maxn],stk[maxn]; pii s1[maxn],s2[maxn]; int quick(int a,int b) { int res=1; while(b) { if(b&1)res=res*a; a=a*a,b>>=1; } return res; } int main() { scanf("%s",s+1); int len=strlen(s+1); for(int i=1;i<=len;i++) { if(s[i]>='0'&&s[i]<='9')s1[++n1]=make_pair(s[i]-'0',1); if(s[i]=='(')stk[++top]=s[i]; if(s[i]=='+'||s[i]=='-') { if(i==1||s[i-1]=='(') { if(s[i]=='+')s1[++n1]=make_pair(s[i+1]-'0',1); else s1[++n1]=make_pair(-(s[i+1]-'0'),1); i++; } else { while(top&&stk[top]!='(') s1[++n1]=make_pair(stk[top],0),top--; stk[++top]=s[i];cnt++; } } if(s[i]=='*'||s[i]=='/') { while(top&&stk[top]!='('&&stk[top]!='+'&&stk[top]!='-') s1[++n1]=make_pair(stk[top],0),top--; stk[++top]=s[i];cnt++; } if(s[i]=='^') { while(top&&stk[top]!='('&&stk[top]=='^') s1[++n1]=make_pair(stk[top],0),top--; stk[++top]=s[i];cnt++; } if(s[i]==')') { while(stk[top]!='(') s1[++n1]=make_pair(stk[top],0),top--; top--; } } while(top)s1[++n1]=make_pair(stk[top],0),top--; pii *a=s1,*b=s2; while(~cnt) { for(int i=1;i<=n1;i++) if(!a[i].ss)printf("%c ",a[i].ff); else printf("%d ",a[i].ff); puts("");cnt--; bool bo=0;n2=0; for(int i=1;i<=n1;i++) { if(!bo&&!a[i].ss) { int num1=b[n2-1].ff,num2=b[n2].ff; if(a[i].ff=='+')num1+=num2; if(a[i].ff=='-')num1-=num2; if(a[i].ff=='*')num1*=num2; if(a[i].ff=='/')num1/=num2; if(a[i].ff=='^')num1=quick(num1,num2); bo=1,n2--;b[n2]=make_pair(num1,1); } else b[++n2]=a[i]; } swap(a,b),swap(n1,n2); } return 0; }
洛谷【P1175】表達式的轉換