NYOJ1272表达式求值(2)

本文解析了一道第九届ACM竞赛题目,介绍了如何通过构建优先级矩阵处理包含特殊运算符的表达式,并使用栈来实现表达式的计算。重点在于理解特殊运算符的功能及其实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



NYOJ1272


    本题是第九届ACM赛题

    

       技巧:    Smax(,)可以看成是  () 的结合,即为一个运算符,代表着,两边的数,分别各个位数之和,在比较大小。千万别被Smax给迷惑了。

                      之后就用 栈 根据优先级进入和弹出了。

                     

#include<stdio.h>
#include<string.h>
int ch[6][6] = { {1,1,1,0,0,0},{0,1,1,0,0,0},{1,1,1,0,1,0},
{ 0,0,0,0,0,0},{1,1,1,0,0,0},{1,1,1,0,0,2}};      //构造优先级  顺序是+ * ( ), #
int stn[1010],n;                               //  在这里专门设置 # # 对应为2 标志结束,防止无限循环
char stc[1010],c;
char an[1010];
int i,kz;
int check(char a)
{
	int sum = 0;
	switch(a)
	{
	case '+' :sum = 0;break;
	case '*' :sum = 1;break;
	case '(' :sum = 2;break;
	case ')' :sum = 3;break;
	case ',' :sum = 4;break;
    case '#' :sum = 5;break;
	}
	return sum;
}
int jisuan(int s)
{

	int t=0;
	while(s!=0)
	{	
		t += s%10;
		s/=10;
	}
	return t;
}
void suan()
{
	n--;
	int l=0,r=0;
	int sum=0;
	switch(stc[c])
	{
	   case '+' :sum = stn[n]+stn[n-1];break;
       case '*' :sum = stn[n]*stn[n-1];break;
	   case ',' :l = jisuan(stn[n]);
		         r = jisuan(stn[n-1]);
				 sum = l>r?l:r;
				 break;
	   case '(' :i++;n++;break;
	}
	
	if(stc[c] != '(')
	stn[n-1] = sum;
//	printf("sum %d\n",sum);
}

void sw(int len)
{
	int k,sum=0;
	for(i = 0;i<len;)
	{
    //	printf("i %c\n",an[i]);
		if(an[i]>= '0' && an[i]<='9')
		{
			
			while( an[i]>= '0' && an[i]<='9' )
			{
				sum = sum*10+an[i]-'0';
				i++;
			}
		
            stn[n]=sum;n++;
		//	printf("sum %d\n",sum);
			sum = 0;
		}
		else if( an[i] == 'S')
		{
			i=i+4;
			kz = 1;
		}
		else 
		{
			int l = check(stc[c-1]);
			int r =	check(an[i]);
			k = ch[l][r];
			if(k == 1)                  //进栈
			{
				stc[c]= an[i];
				c++;i++;
			}
			else if(k==0)             //出栈
			{
				c--;
				suan();
			}else if(k == 2)               //# # 结束 i++  否则,会无限循环
			{
				i++;
			}
			
			
		}
	}
}


int main()
{
	int m,j,len;
	scanf("%d",&m);


	for(j = 0;j<m;j++)
	{
		n=0;c=0;
		stc[c] = '#';c++;              //控制结束
		scanf("%s",&an);
		len = strlen(an);
		an[len] = '#';
		an[len+1]='\0';	

		sw(len+1);
		printf("%d\n",stn[0]);
	}

	return 0;
}

      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值