给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。
输入格式:
输入文件为 expr.in。
输入仅有一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+”和乘法运算符“*”,且没有括号,所有参与运算的数字均为 0 到 2^31-1 之间的整数。输入数据保证这一行只有 0~ 9、+、*这 12 种字符。
输出格式:输出文件名为 expr.out。
输出只有一行,包含一个整数,表示这个表达式的值。注意:当答案长度多于 4 位时,
请只输出最后 4 位,前导 0 不输出。
输入输出样例
1+1*3+4
8
1+1234567890*1
7891
1+1000000003*1
4
对于 30%的数据,0≤表达式中加法运算符和乘法运算符的总数≤100;
对于 80%的数据,0≤表达式中加法运算符和乘法运算符的总数≤1000;
对于 100%的数据,0≤表达式中加法运算符和乘法运算符的总数≤100000。
二、解题思路
思路一
拿到题目,首先分析:
1、乘法一定先做
2、而所有的连乘都是从左往右算
3、更重要的是,如果遇到加号,说明连乘必定完结,这时候再累加即可
定义——块:一段连乘
首先,题目中必有x个加号,将式子分为x+1个块,而这些块最终要做的是相加,所以从左往右算用ans表示当前累加和,t1表示累乘结果,t2表示当前这个数(当前要乘的数),t2的读入方式类似C++的读入优化,按位读入然后乘以10加当前位
框架
do ch=getchar()
switch(ch)
case'+':ans累加
case'*':t1累乘
思路二
输入可以直接scanf(“%d”),然后scanf(“%c”)就行了,不会出错。每一次判断其上一个运算符,进行相应的处理,然后添加到sum中。这里注意一下,如果开int,有可能两个2^31-1相乘,这样可能(我也没试过)会爆。所以都用long long存,保证能AC。最后如果scanf(“%c”)==EOF,则进行最后的处理,然后break即可。只输出后四位,则每一步操作都mod10000即可。
思路三
栈(stack)
(1)读入字符,当其为”+“时,我们先不管;当其为数时则入栈;当其为“*”时我们继续往后读一个数,再从栈中取出一个数与其相乘,将其乘积入栈;
(2)第一项执行完毕后,我们将栈中的元素累加,再输出和。显然,这就是我们想要的答案。
三、参考代码
(1)非栈的思想实现
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
long long shu,sum=0,cj,sg;//记得sum初始值赋为0;cj为其中一段运算(即一段连续的乘积)的值
char ch=0,xg;//ch存储上一个运算符,xg为新读入的运算符
bool tf=true;
while(tf)
{
scanf("%lld",&shu);
tf=scanf("%c",&xg)==1?true:false;//如果下一个没有运算符了,则tf=false,既保证了此次循环的正常运行,又能在下一遍循环跳出
if(ch==0)cj=shu;//如果是刚开始读入,则直接赋值
if(ch=='+')sum=(sum+cj)%10000,cj=shu;//如果上一个操作是加法,则将前一段的值加入到sum中,然后再更新此新段的值
if(ch=='*')cj=(cj*shu)%10000;//如果上一个运算仍是乘法,则将此数乘入本段的值中
if(!tf)sum=(sum+cj)%10000;//如果是最后一个元素,则进行最后的更新
ch=xg;//将下一个读入的运算符作为新的一个循环的上一个运算符,并继续循环
}
printf("%lld",sum);//输出
return 0;
}
(2)栈的思想实践
#include
#include
#include
#include
using namespace std;
string x;
stack <char> s; //算符栈
stack <long long> n; //数字栈
long long ans;
int len;
int main()
{
int i=0;
getline(cin,x);
len=x.length();
while (i<=len-1)
{
int t=0;
bool f=false;
while (x[i]>='0'&&x[i]<='9') //进数字的操作
{
t=t*10+(x[i]-48);
f=true;
i++;
}
if (f)
{
n.push(t%10000);
if (s.size()>=1&&s.top()=='*') //处理乘号
{
int k=n.top();
s.pop();
n.pop(); //先把top的数出栈,再让top-1的数成为top,让他们相乘,再让top出栈,让乘积进栈
k*=n.top(); //这几行码核心内容就是n[--top]=n[top]*n[top+1];
n.pop();
n.push(k%10000);
}
}
if (x[i]=='+'||x[i]=='*')
{
s.push(x[i]);
i++;
}
}
int size=n.size();
for (i=1;i<=size;i++) //计算和
{
ans+=n.top();
n.pop();
ans%=10000;
}
printf("%lld",ans%10000);
return 0;
}