終於會了!可喜可賀!可喜可賀!
計算(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<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<string> 5 #include<cstring> 6 7 using namespace std; 8 9 int number[101],i=0, p=1; 10 char symbol[101],s[256],t[256]; 11 12 void push() { //算符入棧運算 13 symbol[++p]=s[i]; 14 } 15 16 void pop() { //運算符棧頂元素出棧,並取出操作數棧元素完成相應的運算 17 switch (symbol[p--]) { //運算完成之后扔掉運算符,也標志着需要運算的數已經運算完成 18 case '+': { 19 number[p]+=number[p + 1]; 20 break; 21 } 22 case '-': { 23 number[p]-=number[p + 1]; 24 break; 25 } 26 case '*': { 27 number[p]*=number[p + 1]; 28 break; 29 } 30 case '/': { 31 number[p]/=number[p + 1]; 32 break; 33 } 34 case '^': { 35 number[p]=pow(number[p],number[p + 1]); 36 } 37 } 38 } 39 40 bool can() { //判斷運算符的優先級別,建立標志函數,能否進行運算 41 if ((s[i]=='+'||s[i]=='-')&&symbol[p]!='(')//如果不是‘(’,則需要出棧,因為+與-的運算優先級別較低,僅僅比‘(’大 42 return 1; 43 if ((s[i]=='*'||s[i]=='/')&&(symbol[p]=='*'||symbol[p]=='/')) 44 //若遇到乘除且運算符數組中對應的恰好是乘除,則需要出棧 45 return 1; 46 return 0; 47 } 48 49 bool judge(char s[256]) { 50 int top=0,i=0; 51 while (s[i]!='@') { 52 if (s[i]=='(')top++; 53 if (s[i]==')') { 54 if (top>0) top--; 55 else return 0; 56 } 57 i++; 58 } 59 if (top!=0) return 0; //檢測棧是否為空。不空則說明有未匹配的括號 60 else return 1; 61 } 62 63 int main() { 64 gets(s); 65 if(judge(s)==0) { 66 cout<<"NO"; 67 return 0; 68 } 69 70 s[strlen(s)]=')'; 71 symbol[p]='('; 72 while (i<strlen(s)) { 73 while (s[i]=='(') { //左括號處理,壓入左括號,有了左括號才能進行與右括號的匹配 while (symbol[p]!=‘(‘) 74 push(); 75 i++; 76 } 77 int x=0; 78 while (s[i]>='0'&&s[i]<='9') //取數入操作數棧 79 x=x*10+s[i++]-'0'; 80 number[p]=x; 81 do { 82 if (s[i]==')') { //當右括號后面還有右括號時處理 83 while (symbol[p]!=')') 84 pop();//當括號內還有算式沒有算完時進行運算 85 number[--p]=number[p + 1];//當運算完成以后左括號已經沒有意義,所以將指針p移向前一個運算符,並復制所得的結果 86 } else { 87 //根據標志函數值作運算符入棧或出棧運算處理 88 while (can()) 89 pop();// 當可以進行運算時運算,然后壓入一個運算符 90 push(); 91 } 92 i++; 93 } while (i<strlen(s)&&s[i-1]==')');//當檢測到右括號時,可以運算括號內的內容 94 } 95 printf("Result=%d", number[0]);//這個是建立在最后有‘@’的情況下。因為所有的運算全部是建立在括號之內的,所以隨着運算符的減少(運算符減少同時標志着需要操作的數減少)和最后的p--,結果一定保存在number[0]內 96 //printf("Result=%d",number[1]); 97 //如果需要不輸入‘@’的運算式,則只需把從number【0】輸出改為number【1】就好啦~ 98 return 0; 99 }