1356:計算(calc)
時間限制: 1000 ms 內存限制: 65536 KB
【題目描述】
小明在你的幫助下,破密了Ferrari設的密碼門,正要往前走,突然又出現了一個密碼門,門上有一個算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”,求出的值就是密碼。小明數學學得不好,還需你幫他的忙。(“/”用整數除法)
【輸入】
共1行,爲一個算式。
【輸出】
共1行,就是密碼。
【輸入樣例】
1+(3+2)(7^2+69)/(2)
【輸出樣例】
258
思路:後面優先級高,前面內容入棧,否則先算前面內容,計算運算優先組,後面優先級高就前面內容入棧,後面優先級小於等於前面優先組就先算棧內內容 。
#include<iostream>
#include<stack>
#include<cmath>
#include<cstring>
using namespace std;
int const N = 1e5+1;
int x,y;
char ch,ch1;
string s;
stack<int>s1;
stack<char>s2;
int level(char p)
{
if(p=='+' || p=='-')return 1;
if(p=='*' || p=='/')return 2;
if(p == '^')return 3;
return 0;
}
//完成一次基本計算
void calc()
{
int m,n;
char z;
n = s1.top();
s1.pop();
m = s1.top();
s1.pop();
z = s2.top();
s2.pop();
switch(z)
{
case '+':s1.push(m+n);break;
case '-':s1.push(m-n);break;
case '*':s1.push(m*n);break;
case '/':s1.push(m/n);break;
default:s1.push(pow(m,n));
}
return;
}
int main(){
cin >> s;
s = '('+s+')';
int i = 0;
ch = '(';
do
{
if(ch == '(')
{
s2.push('(');
}
//遇到)就計算到(爲止。遇到(之前,棧內所存運算符應該逐級上升,故需反向運算
else if(ch == ')')
{
while(s2.top() != '(')calc();
s2.pop();//彈出(
}
else if(ch >= '0'&&ch <= 9'||ch == '-' && s[i-1] == '(')
//讀到的是數字,把連續的數字變成數值 ,如果是'-'先判斷前面是不是(,是則說明是負號不是減號
{
if(ch == '-')x = 0,y = -1;//是負號則符號設爲-1,初始值爲0
else x = ch-'0',y = 1;//默認符號爲正
ch1 = s[++i];
while(ch1 >= '0' && ch1 <= '9')x = x*10+ch1-'0',ch1 = s[++i];
i--;
x *= y;
s1.push(x);
}
else //ch爲運算符
{
while(level(ch) <= level(s2.top()))//當前運算符不超過棧頂運算,先算棧頂運算
{
calc();
}
s2.push(ch);//直到當前運算符高於棧頂運算符再把運算符存棧
}
}while(ch = s[++i]);
cout << s1.top() << endl;
return 0;
}