建立两个栈
数字栈和符号栈。
读入表达式
遇到数字存入数字栈,遇到左括号和±*/存入符号栈
维护符号栈中符号优先度单调。
如果遇到右括号,那么一直向右计算,直到遇到左括号为止
代码:
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int level[200];//符号优先级
template<class T>
class Stack{
public:
Stack(){
change_len(10);
}
void change_len(int change_size)//更新长度
{
T * tmp = new T[change_size];//新建一个新动态数组
int num1 = min(_size,change_size);
copy(sk,sk+num1,tmp);//复制到新数组
sk = tmp;
_size = change_size;//更新长度
}
int size(){
return this->cap;
}
bool empty(){
return (cap==0);
}
void push(T value){
sk[cap++] = value;
if(cap==_size){
change_len(_size*2);
}
stacktop = value;
}
void pop(){
if(this->size()==0)return ;
else {
cap--;
sk[cap] = 0;
if(cap!=0)stacktop = sk[cap-1];
else stacktop = 0;
}
}
T top(){
return stacktop;
}
private:
T* sk;//栈
T stacktop;//栈顶
int _size=0;//空间
int cap=0;//容量
};
//计算
void calculate(Stack<double>&num,Stack<char>&opera){
double n1 = num.top();//取数字栈中的两个数
num.pop();
double n2 = num.top();//取数字栈中的两个数
num.pop();
double ans;
switch (opera.top()) {
case '+':ans = n2+n1; break;
case '-':ans = n2-n1; break;
case '*':ans = n2*n1; break;
case '/':ans = n2/n1;
}
num.push(ans);//将新数返回数字栈
opera.pop();//符号栈弹栈
}
void pushStack(string s,Stack<double>&num,Stack<char>&opera){
int len = (int)s.length();
double sum = 0;
for(int i = 0;i < len;i++){
if(isdigit(s[i])){//处理数字
sum = sum*10.0+(double)(s[i]-'0');
if(i == len-1||!isdigit(s[i+1]) )
{
num.push((double)sum);
sum = 0;
}
}
//处理运算符
else {
if(s[i] == '(') {//左括号直接入栈
opera.push('(');
continue;
}else if(s[i] == ')'){//右括号要不断弹出符号栈,直到遇到左括号
while(!opera.empty() && opera.top() != '(') calculate(num,opera);
continue;
}
//计算栈顶的情况
while(!opera.empty() && level[s[i]] <= level[opera.top()]) calculate(num,opera);
opera.push(s[i]);
}
}
}
double getResult(string &s,Stack<double>&num,Stack<char>&opera){
pushStack(s,num,opera);
while(!opera.empty()){
calculate(num,opera);
}
return num.top();
}
int main(){
string s="";//需要运算的字符串
Stack<double>num;//数字栈
Stack<char>opera;//符号栈
level['/'] = 3;//运算符优先级
level['*'] = 3;
level['+'] = 2;
level['-'] = 2;
int n;
double ans;
cin>>n;
for(int i = 0;i < n;i++){
while(!num.empty()) num.pop();//清空栈
while(!opera.empty()) opera.pop();
cin>>s;
printf("%.2lf\n",getResult(s,num,opera) );
}
return 0;
}