栈和队列_11
一、HZOJ-266
表达式计算
给出一个表达式,其中运算符仅包含 +,-,*,/,^ 要求求出表达式的最终值。
数据可能会出现括号情况,还有可能出现多余括号情况,忽略多余括号,正常计算即可;
数据保证不会出现大于 max long int的数据;
数据可能会出现负数情况,幂次不可能为负数,除法采用向 0取整。
注意:−9 和 +9 分别代表负数和正数的 9
输入:
共一行,即为表达式。表达式长度不会超过1000
输出:
共一行,既为表达式算出的结果。
样例输入:(2+2)^(1+1)
样例输出: 16
二、题解
1.引库
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <cmath>
using namespace std;
2.代码
- 不采用双栈结构,使用递归来实现
- 根据符号计算符号权重,比如说*/为2,±为1
- 我们对括号里的符号进行附加权重,比如在一个括号里就加100
- 由此我们得到了最低真实权重的符号位置,据此将表达式分为两个部分,可以看作用二叉树向下分裂计算
bool is_operator(char c){
switch(c){
case '+':
case '-':
case '*':
case '/':
case '^': return true;
}
return false;
}
#define INF 0x3f3f3f3f
long long calc(string &s,long long l,long long r){
long long pos=-1,pri=INF-1,cur_pri,temp_pri=0;//默认让数字等于极大值-1
for(long long i=l;i<r;i++){
cur_pri=INF;//默认等于一个极大值
switch(s[i]){
case '(':
temp_pri+=100; break;
case ')':
temp_pri-=100; break;
case '+':
case '-':
cur_pri=1+temp_pri; break;
case '*':
case '/':
cur_pri=2+temp_pri; break;
case '^':
cur_pri=3+temp_pri; break;
}
if( (s[i]=='-'||s[i]=='+') && (i-1<0||is_operator(s[i-1])) ){
cur_pri+=1000;
}
if(pri>=cur_pri){
pri=cur_pri;
pos=i;
}
}
//至此找到在表达式里优先级最低的符号的位置
if(pos==-1){//说明没有运算符,直接获取数字
long long num=0;
for(long long i=l;i<r;i++){
if(s[i]<'0'||s[i]>'9') continue;
num=num*10+(s[i]-'0');
}
return num;
}else{
//cout<<l<<"***"<<pos<<"***"<<r<<endl;
long long a=calc(s,l,pos);
long long b=calc(s,pos+1,r);
//cout<<a<<"***"<<b<<endl;
switch(s[pos]){
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b;
case '^': return pow(a,b);
}
}
return 0;
}
int main(){
string str;
cin>>str;
cout<<calc(str,0,str.size());
return 0;
}