計算(calc.cpp)
【問題描述】
小明在你的幫助下,破密了Ferrari設的密碼門,正要往前走,突然又出現了一個密碼門,門上有一個算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”求出的值就是密碼。小明數學學得不好,還需你幫他的忙。(“/”用整數除法)
【輸入】
輸入檔案calc.in共1行,為一個算式。
【輸出】
輸出檔案calc.out共1行,就是密碼。
【輸入樣例】calc.in
1+(3+2)*(7^2+6*9)/(2)
【輸出樣例】calc.out
258
【限制】
100%的資料滿足:算式長度<=30 其中所有資料在231-1的範圍內。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 int number[101],i=0, p=1; 8 char symbol[101],s[256],t[256]; 9 //p:指向當前的運算子,同時指向當前運算子所對應的運算元 10 void push() //算符入棧運算 11 { 12 symbol[++p]=s[i]; 13 } 14 void pop() //運算子棧頂元素出棧,並取出運算元棧元素完成相應的運算 15 { 16 switch (symbol[p--])//運算完成之後扔掉運算子,也標誌著需要運算的數已經運算完成 17 { 18 case '+': 19 { 20 number[p]+=number[p + 1]; 21 break; 22 } 23 case '-': 24 { 25 number[p]-=number[p + 1]; 26 break; 27 } 28 case '*': 29 { 30 number[p]*=number[p + 1]; 31 break; 32 } 33 case '/': 34 { 35 number[p]/=number[p + 1]; 36 break; 37 } 38 case '^': 39 { 40 number[p]=pow(number[p],number[p + 1]); 41 } 42 } 43 } 44 bool can() //判斷運算子的優先順序別,建立標誌函式,能否進行運算 45 { 46 if ((s[i]=='+'||s[i]=='-')&&symbol[p]!='(') //在括號之內 47 return 1; 48 if ((s[i]=='*'||s[i]=='/')&&(symbol[p]=='*'||symbol[p]=='/')) 49 //若遇到乘除且p對應的恰好是乘除 50 return 1; 51 return 0; 52 } 53 main() 54 { 55 printf("String :");gets(s); 56 s[strlen(s)]=')'; 57 symbol[p]='('; 58 while (i<strlen(s)) 59 { 60 while (s[i]=='(') //左括號處理,壓入左括號,有了左括號才能進行與右括號的匹配 while (symbol[p]!='(') 61 { 62 push(); 63 i++; 64 } 65 int x=0; 66 while (s[i]>='0'&&s[i]<='9') //取數入運算元棧 67 x=x*10+s[i++]-'0'; 68 number[p]=x; 69 do 70 { 71 if (s[i]==')') //當右括號後面還有右括號時處理 72 { 73 while (symbol[p]!='(') 74 pop();//當括號內還有算式沒有算完時進行運算 75 number[--p]=number[p + 1];//當運算完成以後左括號已經沒有意義,所以將指標p移向前一個運算子,並複製所得的結果 76 } 77 else 78 { //根據標誌函式值作運算子入棧或出棧運算處理 79 while (can()) 80 pop();// 當可以進行運算時運算,然後壓入一個運算子 81 push(); 82 } 83 i++; 84 }while (i<strlen(s)&&s[i-1]==')');//當檢測到右括號時,可以運算括號內的內容 85 } 86 printf("Result=%d", number[0]);//因為所有的運算全部是建立在括號之內的,所以隨著運算子的減少(運算子減少同時標誌著需要操作的數減少)和最後的p--,結果一定儲存在number[0]內 87 return 0; 88 }