题目描述
Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等。经过训练,Dr.Kong设计的机器人卡多甚至会计算一种嵌套的更复杂的表达式。
假设表达式可以简单定义为:
-
一个正的十进制数 x 是一个表达式。
-
如果 x 和 y 是 表达式,则 函数min(x,y )也是表达式,其值为x,y 中的最小数。
-
如果 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
sscanf解法
首先要先储备一些知识,下面是我在其他博主哪里学到的我认为对本题有用的一些sscanf的用法
#include<bits/stdc++.h>
using namespace std;
//sscanf的使用
int main()
{
char buf[512];
int t,p;
sscanf("12 3456","%d%n",&t,&p);
//%n意为scanf收到的有效字符数,所以此时的p应为2
printf("%d %d\n",t,p); //12 2
//%[a-z]表示比配a到z中任意字符
sscanf("123aflhaldkjfEFFLJD","%[1-9a-z]",buf);
printf("%s\n",buf); //123aflhaldkjf
//%[^a-z]表示取到a到z中任意字符就停止
sscanf("1234578aldksLKJF","%[^A-Z]",buf);
printf("%s\n",buf); //1234578aldks
//%*[]和%*d,%*c同样,即跳过该范围
sscanf("asdf/1324akldfj;11","%*[asdf]%[^ ]",buf);//即跳过了[asdf],取到了 1324akldfj;11
printf("%s\n",buf); ///1324akldfj;11
sscanf("asdf/1324akldfj;11","%*[^/]%[^;]",buf);
printf("%s\n",buf); // /1324akldfj
return 0;
}
下面是用递归解决的代码,了解了sscanf的一些用法是不难看懂下面的代码的
#include<bits/stdc++.h>
using namespace std;
//sscanf的使用
int start=0;
char str[1000];
int fun()
{
int v,n;
switch(str[start])
{
case 'm':
{
start=start+4;
if(str[start-2]=='n'){
return min(fun(),fun());
}
else{
return max(fun(),fun());
}
}
case 'a':
{
start=start+4;
return fun()+fun();
}
case '(':
case ')':
case ',':
{
start=start+1;
return fun();
}
default:
{
sscanf(str+start,"%d%n",&v,&n);
start=start+n;
return v;
}
}
}
int main()
{
int t;
cin>>t;
getchar();
while(t--){
cin>>str;
start=0;
cout<<fun()<<endl;
}
return 0;
}
stack解法
stack 满足 先入后出
没有迭代器 不可随机访问
stack<int> x ;
int t ;
1. x.push(t) ; //向栈顶插入t 注意: 尾部叫做栈顶
2. x.pop(t) ; //删除栈顶元素
3. size()
4. empty()
5. 与vector类似 但没有clear() 操作
用stack实现将中缀表达式转换为后缀表达式和此题是相似的
首先要建立两个stack,先找运算符,再找操作数。
== 运算符要注意优先级运算,先运算的优先级大。 ==
思想
== 将中缀表达式变为后缀表达式 ==
如果这一个运算符比上一个的优先级高,就需要把上一个的运算符pop了之后再比较top直到大于将此运算符压栈
注意()运算级最高,如果遇到 ‘(’ 则压栈,如果遇到 ‘)’ 则需要把栈里面的运算符依次出栈参与运算,直到遇到 ‘)’ .
详细思想见
解题代码
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
//stack
char ch[1010];
int fun(char ch,int x,int y)
{
if(ch=='+')
return x+y;
else if(ch=='>')
return max(x,y);
else if(ch=='<')
return min(x,y);
}
int main()
{
stack<char>str;
stack<int>num;
int n;
cin>>n;
while(n--){
cin>>ch;
for(int i=0; i<strlen(ch); i++)
{
if(ch[i]=='a'){
str.push('+');
i=i+3;
}
else if(ch[i]=='m'){
if(ch[i+1]=='a'){
str.push('>');
i=i+3;
}
else {
str.push('<');
i=i+3;
}
}
else if(ch[i]>='0'&&ch[i]<='9'){
int n,v;
sscanf(ch+i,"%d%n",&v,&n);
num.push(v);
i=i+n-1;
}
char a;
int b;
int c;
else if(ch[i]==')'){
a=str.top();
str.pop();
b=num.top();
num.pop();
c=num.top();
num.pop();
num.push(fun(a,b,c));
}
}
cout<<num.top()<<endl;
}
}