[普及][NOIP2013 普及组] 表达式求值

题目描述

给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。

输入格式

一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+”和乘法运算符“\times×××”,且没有括号,所有参与运算的数字均为 0 到 2^{31}-1231−1之间的整数。

输入数据保证这一行只有0-90−9、$$+、\times×××这 12种字符。

输出格式

一个整数,表示这个表达式的值。

注意:当答案长度多于 4 位时,请只输出最后4 位,前导0 不输出。

输入数据 1

1+1*3+4

Copy

输出数据 1

8

Copy

输入数据 2

1+1234567890*1

Copy

输出数据 2

7891

Copy

数据规模与约定

对于 30\%30%的数据,0≤0≤表达式中加法运算符和乘法运算符的总数≤100≤100;

对于 80\%80%的数据,0≤0≤表达式中加法运算符和乘法运算符的总数≤1000≤1000;

对于100\%100%的数据,0≤0≤表达式中加法运算符和乘法运算符的总数≤100000≤100000。

题解 

这道题可以说是有点难度,我们先来分析一波。

这道题的输入很明显是中缀表达式,我们程序对逆波兰表达式算起来得心应手,可是对于中缀就没有什么办法了(至少直接算来),我们可以构造树将其转换为后缀的逆波兰,我懒得写

所以我们观察中缀表达式,考虑一下三年级数学讲的带符号搬家,我们发现,除了最开始一个数字,其他数都带有一个操作符。这样我们可以输入第一个数,然后输入操作符和数字。最后用栈模拟。

#include <bits/stdc++.h>
using namespace std;
int x, ans;
char c;
stack<int> s;
const int mod = 10000;
int main()
{
    scanf("%d", &x);
    s.push(x); // 压入最开始的数字
    while (c = getchar()) // getchar
    {
        if (c == '\n') break; // 如果读了个换行符,表示没数了
        scanf("%d", &x); // 否则输入数字
        if (c == '+')
        {

        }
        if (c == '*')
        {

        }
    }
    printf("%d\n", );
    return 0;
}

Copy

很简单吧。一点也不简单

其实我们也可以输入整个字符串,再分解。

这里我们注意乘法运算级更高,需要优先。但是我们计算 1+2*31+2∗3 时,1+21+2 会被先计算,导致得不到正确结果。我们可以把加法直接压进栈,不用操作,乘法即时操作,算完压回栈。只要最后加一遍所有数字就可以了,我们模拟一下。

11,把 11 压进去。

+2+2,把 22 压进去。

*3∗3,把 22 取出,把 2*3=62∗3=6 压进去。

遍历栈:1+6=71+6=7,正确。

#include <bits/stdc++.h>
using namespace std;
int x, ans;
char c;
stack<int> s;
const int mod = 10000;
int main()
{
    scanf("%d", &x);
    s.push(x); // 单独输入
    while (c = getchar())
    {
        if (c == '\n') break;
        scanf("%d", &x);
        if (c == '+')
        {
            s.push(x); // 先压入
        }
        if (c == '*')
        {
            ans = s.top() * x % mod; // 立即计算
            s.pop();
            s.push(ans);
        }
    }
    ans = 0;
    while (!s.empty())
    {
        ans = (ans + s.top()) % mod; // 计算总和,别忘了取模。
        s.pop();
    }
    printf("%d\n", ans);
    return 0;
}

Copy

ACAC CodeCode

#include <bits/stdc++.h>
using namespace std;
int x, ans;
char c;
stack<int> s;
const int mod = 10000;
int main()
{
    scanf("%d", &x);
    s.push(x);
    while (c = getchar())
    {
        if (c == '\n') break;
        scanf("%d", &x);
        if (c == '+')
        {
            s.push(x);
        }
        if (c == '*')
        {
            ans = s.top() * x % mod;
            s.pop();
            s.push(ans);
        }
    }
    ans = 0;
    while (!s.empty())
    {
        ans = (ans + s.top()) % mod;
        s.pop();
    }
    printf("%d\n", ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值