洛谷 P1981 [NOIP2013 普及组] 表达式求值

文章目录

  • [NOIP2013 普及组] 表达式求值
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 样例 #2
      • 样例输入 #2
      • 样例输出 #2
    • 样例 #3
      • 样例输入 #3
      • 样例输出 #3
    • 提示
  • 题意解析
  • 思路解析
  • CODE
  • 注意



[NOIP2013 普及组] 表达式求值

题目链接:https://www.luogu.com.cn/problem/P1981

题目描述

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

输入格式

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

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

输出格式

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

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

样例 #1

样例输入 #1

1+1*3+4

样例输出 #1

8

样例 #2

样例输入 #2

1+1234567890*1

样例输出 #2

7891

样例 #3

样例输入 #3

1+1000000003*1

样例输出 #3

4

提示

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

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

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



题意解析

给你一个只有'+''*'的式子,求结果,数据范围在 i n t int int 之内。

思路解析

  • 直接读入整个式子,然后往后遍历,如果是数字就累加,如果遇到符号,进行不同操作
  • 如果读入了'+':将之前累加的数压入栈,然后对用于累加数字的变量n清零
  • 如果读入了'*':将之前累加的数压入栈,然后对n清零,然后再用双指针读入下一个数,弹栈得到上一个数,将乘法结果算出来后再压入栈内。

我的思路很明了,反正除了乘法就是加法,而乘法优先级更高,那么就在遇到加法的时候不运算只压栈,遇到乘法的时候把值算出来压入栈,最后再加在一起即可。

CODE

#include 
#include 
#include 
#define ll long long		// 本题用int完全够用,不用ll类型

using namespace std;

const int N = 1e8 + 10, mod = 10000;
ll n, stk[N], tt = -1;
string s;

int main(){
	cin >> s;		// 读入整个表达式 
	ll l = s.size();	// 长度 
	for(ll i = 0; i < l; ++i){		// 从头遍历到尾 
		if(s[i] >= '0' && s[i] <= '9') n = n * 10 + (s[i] - '0');	//如果是数字进行累记 
		else if(s[i] == '+'){		// 如果是加法,把之前累计的数字压栈 
			if(n != 0){
				stk[++tt] = n % mod;
				n = 0;
			}
		}else{						// 如果是乘法,将之前累计的数字压栈 
			if(n != 0){
				stk[++tt] = n % mod;
				n = 0;
			}
			++i;
			while(s[i] >= '0' && s[i] <= '9'){		// 读入下一个数字 
				n = n * 10 + (s[i] - '0');
				++i;
			}
			--i;					// 指针回退一个 
			stk[++tt] = n % mod;	// 压栈 
			n = 0;
			ll a = stk[tt--];		// 取出两个数字相乘,得到的结果压栈保存 
			ll b = stk[tt--];
			a = a * b;
			stk[++tt] = a % mod;
		}
	}
	
	stk[++tt] = n % mod;			// 如果最后一个符号是+,则余下一个数字,压栈 
	
	ll ans = 0;
	while(tt >= 0){					// 将栈内数字全部累加得到答案 
		ans = (ans + stk[tt--]) % mod; 
	}
	cout << ans;
} 

注意

  • 每次遇到符号压入之前累计的数字时,需要判断是否为 0 0 0,尤其是在乘法时,因为会有连乘的存在,我们在运算完第一个乘法时,累计数字n会被清零,此时我们不能再对它压栈,否则连乘的答案将被乘上 0 0 0 最终错误。

本题很像之前那个表达式求值啊,不过那个更复杂 <_>。

你可能感兴趣的:(#,栈,算法,笔记,c++)