题目描述
时间限制:500ms 内存限制:256.0MB
问题描述
给定一个只包含加(\(+\))、减(\(-\))、乘(\(*\))三种运算的\(n\)个字符的合法表达式,请求出该表达式的值对\(2527\)取余后的结果。
输入格式
第二行输入一个字符串\(S\),表示一个合法表达式。
输出格式
输出一个整数,表示该表达式的值对\(2527\)取余后的结果。
样例输入1
(26*3*8)+(1*11)-(9*15*9)
样例输出1
1947
样例输入2
(510*510+208)-(511*511-813)
样例输出2
0
数据规模和约定
\(1\leq |S|\leq 5×10^6\),其中\(|S|\)为字符串\(S\)的长度。
保证表达式仅包含数字、左右括号、加号、减号、乘号,且表达式中的数字均为整数且\(\in [0, 2527)\)。
提示
请使用较快的读入方式。
解析
可以利用中缀表达式转后缀表达式的方法在计算。转化过程可以运用栈。
转化:
\(s1[top]\) 用字符串模拟出栈的效果,方便存储后缀表达式,\(top\)为栈顶。
\(s2\) 用于临时存贮运算符。
\(str\) 用于存储中缀表达式。
按顺序依次遍历\(str_i(0\leq i\leq len)\)。若为操作数,则直接入栈\(s1\);若为左括号\((\),则直接入栈\(s2\);若为右括号\(')'\),则栈\(s2\)将左括号\((\)以上的所有运算符一次出栈并入栈\(s1\);若为运算符,则当栈\(s2\)栈顶元素为括号或者栈顶元素运算优先级比\(str_i\)低时或者栈为空时直接入栈,否则依次出栈并入栈到\(s1\)中,直到栈顶元素满足要求为止,再将\(str_i\)入栈\(s2\)。
最终将栈\(s2\)中剩余元素依次出栈并入栈到\(s1\)中。
得出后缀表达式。
求值:
\(st\) \(int\)类型栈,用于存储操作数。
按顺序依次遍历栈\(s1_i(0\leq i\leq len)\)。若\(isdigit(s1_i)\),则找到\(j\)并满足\(!isdigit(s1_{j+1})\),将操作数记下并压入栈\(st\)中;若为运算符,则将栈\(st\)弹出两个数并作出相应的运算,再将结果压入栈\(st\)中。
栈\(st\)的栈顶元素即为该表达式的运算值。
#include <iostream>
#include <stack>
#include <cctype>
#include <string>
using namespace std;
const int mod = 2527;
stack<char> s2;
string str, s1 = "";
int priority(char symb) {
if (symb == '(' || symb == ')') return 0;
if (symb == '+' || symb == '-') return 1;
return 2;
}
int calc(int a, int b, char symb) {
if (symb == '+') return a + b;
else if (symb == '-') return a - b;
else return a * b;
}
string Infix_to_Suffix() {
int str_len = str.length();
while (!s2.empty()) s2.pop();
for (int i = 0; i < str_len; i++) {
if (str[i] >= '0' && str[i] <= '9') {
s1 += str[i];
if (!(str[i + 1] >= '0' && str[i + 1] <= '9')) s1 += '.';
} else if (str[i] == '(') s2.push(str[i]);
else if (str[i] == ')') {
while (s2.top() != '(')
s1 += s2.top(), s2.pop();
s2.pop();
} else {
while (!s2.empty() && priority(str[i]) <= priority((char)s2.top()))
s1 += s2.top(), s2.pop();
s2.push(str[i]);
}
}
while (!s2.empty())
s1 += s2.top(), s2.pop();
return s1;
}
int cnt(string s1) {
stack<int> st;
int s1_len = s1.length(), ans = 0;
while (!st.empty()) st.pop();
for (int i = 0, temp; i < s1_len; i++) {
if (s1[i] == '.') continue;
if (isdigit(s1[i])) {
temp = 0;
while (s1[i] >= '0' && s1[i] <= '9') temp = temp * 10 + (s1[i++] - '0');
st.push(temp % mod);
} else {
int a = st.top(); st.pop();
int b = st.top(); st.pop();
st.push(calc(b, a, s1[i]) % mod); //注意运算顺序和取模
}
}
return (st.top() + mod) % mod; //经过数学运算取模最终结果不能为负数
}
int main(int argc, char** argv) {
cin >> str;
cout << cnt(Infix_to_Suffix()) << endl;
return 0;
}
-end-