表示式求值-中綴轉字首表示式
阿新 • • 發佈:2021-07-30
題目描述
時間限制: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\)
保證表示式僅包含數字、左右括號、加號、減號、乘號,且表示式中的數字均為整數且\(\in [0, 2527)\)。
提示
請使用較快的讀入方式。
解析
可以利用中綴表示式轉字尾表示式的方法在計算。轉化過程可以運用棧。
轉化:
\(s1[top]\) 用字串模擬出棧的效果,方便儲存字尾表示式,\(top\)為棧頂。
\(s2\) 用於臨時存貯運算子。
\(str\) 用於儲存中綴表示式。
按順序依次遍歷\(str_i(0\leq i\leq len)\)。若為運算元,則直接入棧\(s1\)
最終將棧\(s2\)中剩餘元素依次出棧併入棧到\(s1\)中。
得出字尾表示式。
求值:
\(st\) \(int\)型別棧,用於儲存運算元。
按順序依次遍歷棧\(s1_i(0\leq i\leq len)\)
棧\(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-