表达式求值
时间限制:
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
来源
- 河南省第九届省赛 上传者
- onlinejudge
和数据结构这本书上的表达式求值类似。
在这里只不过多了smax运算符。仔细分析后我们可以把smax的功能让,来实现。
主要就是处理好运算符的优先级即可~ 根据数据结构上的优先级 很快可以找到本题的优先级
然后就是使用栈来模拟操作了、
遍历表达式,每次遇到数字就将这个数入数字栈,如果遇到运算符就和当前栈顶的运算符相比较 ,根据运算符优先级的不同来进行计算。
具体代码如下:
#include <stdio.h>
#include<string.h>
#include<stack>
using namespace std;
char row[]={"+,*()#"};
//运算符优先级
char mm[10][10]={
">><<>>",
"<><<>>",
">>><>>",
"<<<<=>",
">>>=>>",
"<<<<<="
};
//取得运算符所有的行号
int getRow(char c)
{
for(int i=0;i<6;i++)
{
if(c==row[i])
return i;
}
}
//获得优先级
char getPiro(int x,int y)
{
return mm[x][y];
}
//smax操作
int mod(int n)
{
int sum=0;
while(n>0)
{
sum+=n%10;
n=n/10;
}
// printf("sum=%d \n",sum);
return sum;
}
//根据不同的运算符 执行不同的操作
int caculate(int a,int b,char threat)
{
switch(threat)
{
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case ',': return mod(a)>mod(b)?mod(a):mod(b);
}
}
int main()
{
char str[1050];
int t;
stack<int> num;
stack<char> op;
scanf("%d",&t);
while(t--)
{
op.push('#');
scanf("%s",str);
int len=strlen(str);
str[len]='#';
str[len+1]='\0';
len++;
int temp=0;
bool in=false;
for(int i=0;i<len;i++)
{
in=false;
//如果遇到数字 一直执行到读取数字结束
while(str[i]>='0'&&str[i]<='9'&&i<len)
{
temp=temp*10+str[i]-'0';
i++;
in=true;
}
if(in) num.push(temp),temp=0;
//如果遇到运算符 就和当前栈顶的运算符相比较
if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='('||str[i]==')'||str[i]==','||str[i]=='#')
{
// op.push(str[i]);
bool exit=true;
while(exit)
{
switch(getPiro(getRow(op.top()),getRow(str[i])))
{
case '<': op.push(str[i]),exit=false;break;
case '=': op.pop(),exit=false;break;
case '>': {
char threat =op.top();op.pop();
int a=num.top();num.pop();
int b=num.top();num.pop();
// printf("%d %c %d\n",a,threat,b);
num.push(caculate(a,b,threat));//计算a threat b
break;
}
}
}
}
}
while(!op.empty()) op.pop();
printf("%d\n",num.top());num.pop();
}
return 0;
}