NYOJ 1272 表达式求值 (字符串处理)

表达式求值

时间限制: 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

思路:不管Smax,把‘,’当做一种新的运算代替Smax,推出优先级表就好做了。。

代码:

#include<stdio.h>
#include<stack>
#include<string.h> 
using namespace std;
char ope[10]="+-*,()#";
char prec[10][8]={
				//   +-*,()#    //运算符优先级 
		            ">><><>>",
		            ">><><>>",
		            ">>>><>>",
		            "<<<><>>",
		            "<<<<<=>",
		            ">>>>=>>",
		            "<<<<<<=", 
                };
int getNum(char c)
{
	for(int i=0;i<strlen(ope);i++)
	{
		if(ope[i]==c) return i;
	}
}
char getPrec(char a,char b)//返回a,b优先级 
{
	int x=getNum(a);
	int y=getNum(b);
	return prec[x][y]; 
}
int mod(int n)//取余求和 
{
	int sum=0;
	while(n>0)
	{
		sum+=n%10;
		n=n/10;
	}
	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()
{  
    int t;
	scanf("%d",&t);
	char str[1050];
	stack<int>num;
	stack<char> op;
	while(t--)
	{
	    scanf("%s",str);
		op.push('#');
	    int len=strlen(str);
	    str[len]='#';
	    str[len+1]='\0';
	    len++;
	    bool input=false;//标记接受数字 
	    int temp=0;
		for(int i=0;i<len;i++)
		{
		   if(str[i]>='0'&&str[i]<='9')//处理数字 
		   {
		         input=true;
				 temp=temp*10+str[i]-'0';
		   }
		   else if(str[i]=='+'||str[i]=='-'||str[i]==','||str[i]=='*'||str[i]=='('||str[i]==')'||str[i]=='#')
		   {
		      if(input)//没有接收数字就不push 
			  {
			  	num.push(temp);
		        temp=0;
		        input=false;
			  }
			  int flag=true;//当栈顶元素优先级大于str[i]时,一直运算 
			  while(flag)
			  {
				  	switch(getPrec(op.top(),str[i]))
					  {
					  	case '<': op.push(str[i]);flag=false;break;//栈顶元素优先级低,运算符入栈 
					  	case '=': op.pop();flag=false;break;//去括号 
					  	case '>': {
					  		        int a=num.top();num.pop();
					  		        int b=num.top();num.pop();
					  		        char threat=op.top();op.pop();
					  		    //     printf("%d %c %d\n",a,threat,b);
					  		        num.push(caculate(a,b,threat));
							 		break;
								  }
					  }
			  }
				  
		   }
		
		}	
        printf("%d\n",num.top());//输出栈顶元素 
    	num.pop();
	}	
} 

 








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值