表达式求值
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
假设表达式定义为: 1. 一个十进制的正整数 X 是一个表达式。 2. 如果 X 和 Y 是 表达式,则 X+Y, X*Y 也是表达式; 优先级高于+. 3. 如果 X 和 Y 是 表达式,则 函数 Smax(X,Y)也是表达式,其值为:先分别求出 X ,Y 值的各位数字之和,再从中选最大数。 4.如果 X 是 表达式,则 (X)也是表达式。 例如: 表达式 12(2+3)+Smax(333,220+280) 的值为 69。 请你编程,对给定的表达式,输出其值。
输入
【标准输入】 第一行: T 表示要计算的表达式个数 (1≤ T ≤ 10) 接下来有 T 行, 每行是一个字符串,表示待求的表达式,长度<=1000
输出
【标准输出】 对于每个表达式,输出一行,表示对应表达式的值。
样例输入
3
12+2*3
12*(2+3)
12*(2+3)+Smax(333,220+280)
样例输出
18
60
69
优先级略坑
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<math.h>
using namespace std;
//表达式求值
//中缀式转后缀式
int Judge(char c1,char c2)//比较栈顶字符和当前字符
{
if(c1=='#')
{
if(c2=='#')
return -1;//两元素消去
return 1;//当前元素入栈
}
if(c1=='(')
{
if(c2==')')
return -1;//两元素消去
return 1;//当前元素入栈
}
if(c1=='+')
{
if(c2=='+'||c2==')'||c2=='#')
return 0;//栈顶出栈
return 1;//当前元素入栈
}
if(c1=='*')
{
if(c2=='*'||c2==')'||c2=='#'||c2=='+')
return 0;//栈顶出栈
return 1;//当前元素入栈
}
if(c1=='S')
{
if(c2=='(')
return 1;//当前元素入栈
return 0;//栈顶出栈
}
return 2;//随便返回
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
char str_1[2222];
scanf("%s",str_1);
int len_str_1=strlen(str_1);
str_1[len_str_1++]='#';
char str_2[2222];
int len_str_2=0;
stack<char>q;
q.push('#');
for(int i=0; i<len_str_1; i++)
{
if(str_1[i]>='0'&&str_1[i]<='9')
{
while(str_1[i]>='0'&&str_1[i]<='9')
str_2[len_str_2++]=str_1[i++];
str_2[len_str_2++]=' ';
i--;
}
else if(str_1[i]=='+'||str_1[i]=='*'||str_1[i]=='('||str_1[i]==')'||str_1[i]=='S'||str_1[i]=='#')
{
if(Judge(q.top(),str_1[i])==-1)
q.pop();
else if(Judge(q.top(),str_1[i])==1)
q.push(str_1[i]);
else if(Judge(q.top(),str_1[i])==0)
{
while(Judge(q.top(),str_1[i])==0)
{
str_2[len_str_2++]=q.top();
q.pop();
str_2[len_str_2++]=' ';
}
if(Judge(q.top(),str_1[i])==-1)
q.pop();
else if(Judge(q.top(),str_1[i])==1)
q.push(str_1[i]);
}
}
}
// for(int i=0; i<len_str_2; i++)
// printf("%c",str_2[i]);
// printf("\n");//测试后缀式
//后缀式测试没问题
stack<long long int>num;
for(int i=0; i<len_str_2; i++)
{
if(str_2[i]>='0'&&str_2[i]<='9')//遇到数字就入栈
{
int num_1=0;
while(str_2[i]>='0'&&str_2[i]<='9')
num_1=num_1*10+str_2[i++]-'0';
num.push(num_1);
}
else if(str_2[i]!=' ')//遇到操作符
{
if(str_2[i]=='+')
{
int num_1=num.top();
num.pop();
int num_2=num.top();
num.pop();
num.push(num_1+num_2);
}
else if(str_2[i]=='*')
{
int num_1=num.top();
num.pop();
int num_2=num.top();
num.pop();
num.push(num_1*num_2);
}
else if(str_2[i]=='S')
{
int num_1=num.top();
num.pop();
int flag_1[100];
int len_1=0;
while(num_1)
{
flag_1[len_1++]=num_1%10;
num_1=num_1/10;
}
for(int i=0; i<len_1; i++)
num_1+=flag_1[i];
int num_2=num.top();
num.pop();
int flag_2[100];
int len_2=0;
while(num_2)
{
flag_2[len_2++]=num_2%10;
num_2=num_2/10;
}
for(int i=0; i<len_2; i++)
num_2+=flag_2[i];
num.push(max(num_1,num_2));
}
}
}
printf("%I64d\n",num.top());
}
return 0;
}
给几组测试数据
输入
5
12+2+2*3
666+1000*(60+600+Smax(33,1000))
12*(2+3)+Smax(33,2)
12*(2+3)+Smax(32,2)+15*15
500+50*(12*(2+3)+Smax(32,2)+15*15)
输出
20
666666
66
290
15000