题目:
表达式求值
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等。经过训练,Dr.Kong设计的机器人卡多甚至会计算一种嵌套的更复杂的表达式。
假设表达式可以简单定义为:
1. 一个正的十进制数 x 是一个表达式。
2. 如果 x 和 y 是 表达式,则 函数min(x,y )也是表达式,其值为x,y 中的最小数。
3. 如果 x 和 y 是 表达式,则 函数max(x,y )也是表达式,其值为x,y 中的最大数。
4.如果 x 和 y 是 表达式,则 函数add(x,y )也是表达式,其值为x,y 之和。
例如, 表达式 max(add(1,2),7) 的值为 7。
请你编写程序,对于给定的一组表达式,帮助 Dr.Kong 算出正确答案,以便校对卡多计算的正误。
-
输入
-
第一行: N 表示要计算的表达式个数 (1≤ N ≤ 10)
接下来有N行, 每行是一个字符串,表示待求值的表达式
(表达式中不会有多余的空格,每行不超过300个字符,表达式中出现的十进制数都不
超过1000。)
输出
- 输出有N行,每一行对应一个表达式的值。 样例输入
-
3 add(1,2) max(1,999) add(min(1,1000),add(100,99))
样例输出
-
3 999 200
来源
- 第四届河南省程序设计大赛 上传者
- 张云聪
-
第一行: N 表示要计算的表达式个数 (1≤ N ≤ 10)
代码清晰明了,这些代码的精华在于sscanf的应用,巧妙的在字符串中提取出了我们要的整数,大牛的思路就是妙,长见识了
参考博客:http://blog.csdn.net/niushuai666/article/details/7182018
代码:
#include <cstdio>
#include <cstring>
#include <cctype>
#include <string>
#include <set>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define mod 10000007
#define debug() puts("what the fuck!!!")
#define N 100100
#define M 1000000+10
#define ll long long
using namespace std;
char str[1000];
stack<char>ope;//存储操作符
stack<int>num;//存储数字
char tchar;//临时操作符
int tnum,wei;//存放临时数字
char getope(char a,char b)
{
if(a=='a')//add
return '+';
else if(a=='m'&&b=='a')//max
return '>';
else//min
return '<';
}
int calc(int a,int b,char c)
{
if(c=='+')
return a+b;
else if(c=='<')
return min(a,b);
else if(c=='>')
return max(a,b);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
while(!ope.empty())ope.pop();
while(!num.empty())num.pop();
scanf("%s",str);
int len=strlen(str);
for(int i=0;i<len;i++)
{
if(str[i]=='a'||str[i]=='m')
{
tchar=getope(str[i],str[i+1]);//获得操作符
ope.push(tchar);
i+=2;//把i的下标跳过题目定义的操作符
}
else if(str[i]>='0'&&str[i]<='9')
{
sscanf(&str[i],"%d%n",&tnum,&wei);//格式化str[i]之后的字符串,读取数字,以及数字的位数(大牛太厉害了,这个真的妙)
i+=wei-1;//跳过数字位
num.push(tnum);
}
else if(str[i]==')')//遇到右括号开始计算
{
int b=num.top();
num.pop();
int a=num.top();
num.pop();
char cal=ope.top();
ope.pop();
num.push(calc(a,b,cal));
}
}
printf("%d\n",num.top());
}
return 0;
}
2018年05月07日18:31:04更新
#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define inf 0x3f3f3f3f
typedef long long ll;
const int N = 1000 + 20;
stack<char> st_ch;
stack<int> st_num;
char get_op(char a, char b)
{
if (a == 'a')
return '+';
if (a == 'm' && b == 'a')
return '>';
return '<';
}
int calc(int a, int b, char c)
{
if (c == '+')
return a + b;
if (c == '<')
return min(a, b);
if (c == '>')
return max(a, b);
}
int main()
{
//freopen("test.in", "r", stdin);
int t;
string s;
cin >> t;
while (t--)
{
while (!st_ch.empty())
st_ch.pop();
while (!st_num.empty())
st_num.pop();
cin >> s;
s += "+0";
int len = s.size();
string str_num = "";
for (int i = 0; i < len; i++)
{
if (isdigit(s[i]))
{
str_num += s[i];
continue;
}
if (str_num != "")
{
int num = atoi(str_num.c_str());
st_num.push(num);
str_num = "";
}
if (s[i] == 'a' || s[i] == 'm')
{
char ch = get_op(s[i], s[i + 1]);
st_ch.push(ch);
i += 2;
}
if (s[i] == ')')
{
int a = st_num.top();
st_num.pop();
int b = st_num.top();
st_num.pop();
char ch = st_ch.top();
st_ch.pop();
st_num.push(calc(a, b, ch));
}
}
printf("%d\n", st_num.top());
}
return 0;
}