小韦老师@NOIP 普及组-2013-表达式求值
题目:
描述
给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。
输入
输入仅有一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+ ”和乘法运算符 “ * ”,且没有括号, 所有参与运算的数字均为 0 到 231-1 之间的整数。输入数据保证这一行只有 0~9、+ 、* 这 12 种字符。
输出
输出只有一行 , 包含一个整数,表示这个表达式的值
注意:当答案长度多于 4 位时,请只输出最后 4 位 ,前导 0 不输出
输入样例1
1+1*3+4
输出样例1
8
输入样例2
1+1234567890*1
输出样例2
7891
输入样例3
1*100000003+1
输出样例3
4
提示
样例1 计算的结果为 8, 直接输出 8。
样例2 计算的结果为 1234567891,输出后 4 位,即 7891.
样例3 计律的结果为 1000000004, 输出后 4 位,即 4。
题解:
思路:
整体思路:
用一个栈来存储数字,若输入的计算符号是 + 时,则后面的数字入栈;若输入的计算符号是 * ,则将栈顶元素出栈,与后一个数字相乘,结果再压入栈中。最后将栈中留下的元素都累加起来即可。
注意:这里是要模 10000 (只要后面 4 位)的结果。
具体步骤:
1.定义一个栈,用来存储输入的数字或者中间乘积的结果:
stack<int> st;
2.定义一个常量,用来作为模的数,数值为 10000,因为题目要保留后面 4 位数:
const int M = 10000; // 作为模数
3.定义 2 个变量:
int a; // 用来接收数字
char op; // 用来接收运算符
4.将式子的第一个数字输入,并且将其压栈:
cin >> a; // 输入式子的第一个数字
st.push(a % M); // 将第一个数字模 M,并压入栈中
5.采用快读的方式每次读入一个计算符号和一个数字,并做以下操作:
- 若计算符号是 *,则取得栈顶元素,将栈顶元素出栈,并且将栈顶元素和刚刚读入的数字的乘积压栈:
if (op == '*') { // 若计算符号是 *
int t = st.top(); // 取得栈顶元素
st.pop(); // 栈顶元素出栈
st.push(a * t % M); // 将栈顶元素乘以刚刚读入的数字,模 M,再压栈
}
- 若计算符号是 +,则将刚刚读入的数字压栈
else { // 若计算符号是 +
st.push(a % M); // 将刚刚读入的数字模 M,再压栈
}
6.定义一个变量,用来存储结果:
int ans = 0; // 用来存储结果,记得初始化为 0
7.接下来就是要将栈中的元素都加起来:
while(st.size() > 0) { // 当栈的大小大于 0 时
ans += st.top() % M; // 取得栈顶元素,模 M,累加到 ans 中
st.pop(); // 栈顶元素出栈
}
8.输出结果:
cout << ans % M; // 输出 ans % M,模 M 是为了保险
完整代码:
#include <bits/stdc++.h>
using namespace std;
stack<int> st; // 用来存储输入的数字或者中间乘积的结果
const int M = 10000; // 作为模数
int main() {
int a; // 用来接收数字
char op; // 用来接收运算符
cin >> a; // 输入式子的第一个数字
st.push(a % M); // 将第一个数字模 M,并压入栈中
while (cin >> op >> a) { // 采用快读的方式读入一个计算符号和一个数字
if (op == '*') { // 若计算符号是 *
int t = st.top(); // 取得栈顶元素
st.pop(); // 栈顶元素出栈
st.push(a * t % M); // 将栈顶元素乘以刚刚读入的数字,模 M,再压栈
} else { // 若计算符号是 +
st.push(a % M); // 将刚刚读入的数字模 M,再压栈
}
}
int ans = 0; // 用来存储结果,记得初始化为 0
while(st.size() > 0) { // 当栈的大小大于 0 时
ans += st.top() % M; // 取得栈顶元素,模 M,累加到 ans 中
st.pop(); // 栈顶元素出栈
}
cout << ans % M; // 输出 ans % M,模 M 是为了保险
return 0;
}