[刷题之旅no7][NOIP2013 普及组] 表达式求值

本质:
中缀表达式转后缀表达式,后缀表达式求值
本题简化了:
换成了只有乘法和加法,而且所有数字均大于0,那真是太简单了点。而且数字大小连int都可以存得小(真是道婴幼儿级别的题目啊,中缀转后缀得难点没了,完了也没有高精度计算是吧。。。)
既然这么简单,那就给你设计一个思路就好了。
1.读取
2.入栈,遇到乘法出栈,出栈的时候要和惩罚后面的结果一起运算,还是不够可以啊,结果入栈,看来还是有点难度
我这个思路的难度就是,先把乘法和加法一起入栈,并且把所有数字都转化过来,最后再遍历运算即可。
3.把加乘混合表达式更改乘加法表达式即可
4.取后四位,直接对10000取余就行
出现了好多逻辑错误啊:
第一点就是在将字符串转化为数字的过程中,
如果遇到的是乘法,则需要对其后面的数字进行运算,而如果遇到的是数字,则从他开始就可以了,而且对于运算过程中i++和终止判断的问题
当遇到乘法的时候,需要先I++;然后计算,然后判断下一个是不是运算符,将计算出的数字入栈
当遇到数字的时候,先计算,然后判断下一个是不是运算符,如果是则break;如果不是则i++。这两个顺序是不一样的。
好吧,我把这道题想得太简单了,只得到了20分,让我看看是怎么回事呢。
看来有极大的可能性,溢出了。。。
如何防止溢出呢?
1.利用高精度计算,也就是利用数组进行加法和乘法运算
2.在计算过程中不断取余。
我现在选择第二种方法
操作过程:
在转化数字或者进行乘法的时候,进行取余,使得结果不超出范围

stack[top]=((stack[top]%10000)*(trans%10000))%10000;//风险地区
stack[top]=trans%10000;

可是再提交,只得到了八十分。说明存在错误。
过了,原来是我审题出错了,题目要求是运算符数量小于10万,我以为整个表达式数量小于十万呢.
我的代码:

#include
char cal[1000005];
long long trans=0,stack[1000005]={0},top=0;
int main()
{
	scanf("%s",cal);
	for(int i=0;cal[i]!='\0';i++)
	{
		if(cal[i]=='*')//等于乘法出栈,可是此时还需要后面一个数字才行啊。 
		{
			trans=0;
			while(1)//如果是个位数呢? 
			{
				i++;//先加后算 
				trans=trans*10+(cal[i]-'0');
//				trans=trans%10000;
				if(cal[i+1]=='*'||cal[i+1]=='+'||cal[i+1]=='\0')
				{
					break;
				}	
			}
			//出栈,计算,入栈 
//			printf("trans=%lld\n",trans);
			stack[top]=((stack[top]%10000)*(trans%10000))%10000;//风险地区 
		}
		else if(cal[i]=='+')//加法当作-1入栈 
		{
			continue;//遇到加法直接不管,最后结果相加就行 
		}
		else//数字
		{
			trans=0;
			while(1)//如果是个位数呢? 
			{
				trans=trans*10+(cal[i]-'0'); 
//				trans=trans%10000;
				if(cal[i+1]=='*'||cal[i+1]=='+'||cal[i+1]=='\0')
				{
					break;
				}
				i++;
			}
			//入栈
			top++;
			stack[top]=trans%10000; 
		} 
	}
	//遍历栈,计算结果(形式就是)
//	printf("%lld\n",top);
//	for(int i=0;i<=top;i++)
//	{
//		printf("%lld\n",stack[i]);//出现问题了,stack里面存的都是0; 
//	}
	trans=0;
	for(int i=0;i<=top;i++)
	{
		trans=trans+stack[i];//结果取余还是错误答案 ,所以说明在计算stack的时候就出现了问题。那么将stack取余即可 
//		trans=trans%10000;
	}
	printf("%lld",trans%10000);
	return 0;
}

不过看来题意并没有想要我用字符串把整个表达式储存起来得意思?
看来又要学习一下大佬的思路了呢:
震惊一百年!
1.直接scanf,让%d和%c交替处理就好了啊!
超清晰的思路:
利用栈
先读入一个数
然后读取一个符号加上一个数
如果是乘法,则栈顶弹出运算,乘积入栈
加法就直接入栈
最后把栈中相加
输出总和!
我日!好清晰啊!

你可能感兴趣的:([刷题之旅])