本质:
中缀表达式转后缀表达式,后缀表达式求值
本题简化了:
换成了只有乘法和加法,而且所有数字均大于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<stdio.h>
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交替处理就好了啊!
超清晰的思路:
利用栈
先读入一个数
然后读取一个符号加上一个数
如果是乘法,则栈顶弹出运算,乘积入栈
加法就直接入栈
最后把栈中相加
输出总和!
我日!好清晰啊!