1. 程式人生 > 實用技巧 >暑期訓練3 Gym - 102309A APA of Orz Pandas 棧,逆波蘭表示式,模擬

暑期訓練3 Gym - 102309A APA of Orz Pandas 棧,逆波蘭表示式,模擬

暑期訓練3 Gym - 102309A APA of Orz Pandas 棧,逆波蘭表示式,模擬

題意

給出一個包含乘,除,加,減,取餘的中綴表示式,要求轉化為JAVA的大整數的運算模式,且運算元素的順序要求嚴格相等。例如

Input

\[a + b + c \\ (a+b)+c \\ a+(b+c) \\ (a+b)\%(c+d) \]

Output

\[a.add(b).add(c) \\ a.add(b).add(c); \\ a.add(b.add(c)) \\ a.add(b).remainder(c.add(d)) \]

The length of the expressions will not exceed 1000.

分析

考慮到難點主要在於括號,而逆波蘭表示式正好可以很好的解決問題,因此這道題的思路就是轉化為逆波蘭表示式再把相應的加法改成"add"....

中綴表示式轉逆波蘭表示式

  • 建立一個用於存放運算子的棧,逐一掃描該中綴表示式中的元素

    • 如果遇到一個數,輸出該數

    • 如果遇到左括號,把左括號入棧

    • 如果遇到右括號,不斷取出棧頂並輸出,直到棧頂為左括號,然後把左括號出棧

    • 如果遇到運算子,只要棧頂符號優先順序不低於新符號,就不斷取出棧頂並輸出 ,最後把新符號入棧。

  • 依次取出並輸出棧中所有的剩餘符號

逆波蘭表示式求值

  • 建立一個用於存數的棧,逐一掃描該字尾表示式中的元素
    • 如果遇到一個數,則把這個數入棧
    • 如果遇到運算子,就取出棧頂的兩個數進行計算,把結果入棧
  • 掃描完成後,棧中只剩下一個數,就是逆波蘭表示式的值

注意此題的運算數是字母,且可能是多個字母

程式碼

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    string ss;
    vector<string> res;
    stack<string> st;
    stack<string> ans;
    while (cin >> ss) {
        while (!st.empty()) st.pop();
        while (!ans.empty()) ans.pop();
        res.clear();
        for (int i = 0; i < ss.length(); i++) {
            if ((ss[i] >= 'a' && ss[i] <= 'z') || (ss[i] >= 'A' && ss[i] <= 'Z')) {
                string tmp = "";
                while ((ss[i] >= 'a' && ss[i] <= 'z') || (ss[i] >= 'A' && ss[i] <= 'Z')) tmp.push_back(ss[i++]);
                i--;
                res.push_back(tmp);
            }
            else if (ss[i] == '(') {
                string tmp = "(";
                st.push(tmp);
            }
            else if (ss[i] == ')') {
                while (st.top() != "(") res.push_back(st.top()), st.pop();
                st.pop();
            }
            else {
                string tmp = "";
                tmp.push_back(ss[i]);
                if (ss[i] == '*' || ss[i] == '/' || ss[i] == '%') while (!st.empty() && (st.top() == "*" || st.top() == "/" || st.top() == "%")) res.push_back(st.top()), st.pop();
                else if (ss[i] == '+' || ss[i] == '-') while (!st.empty() && (st.top() != "(")) res.push_back(st.top()), st.pop();
                st.push(tmp);
            }
        }
        while (!st.empty()) res.push_back(st.top()), st.pop();
        for (int i = 0; i < res.size(); i++) {
            if (res[i] != "*" && res[i] != "/" && res[i] != "+" && res[i] != "-" && res[i] != "%") {
                ans.push(res[i]);
            }
            else {
                string a1 = ans.top(); ans.pop();
                string a2 = ans.top(); ans.pop();
                    string tmp = "";
                    tmp += a2;
                    if (res[i] == "+") tmp += ".add(";
                    else if (res[i] == "-") tmp += ".substract(";
                    else if (res[i] == "*") tmp += ".multiply(";
                    else if (res[i] == "/") tmp += ".divide(";
                    else if (res[i] == "%") tmp += ".remainder(";
                    tmp += a1;
                    tmp += ')';
                    ans.push(tmp);
                }
        }
        cout << ans.top() << '\n';
    }
}