1. 程式人生 > 其它 >牛客華為機試HJ50

牛客華為機試HJ50

原題傳送門

1. 題目描述

2. Solution1

括號替換,計算

import sys

for line in sys.stdin:
    s = line.strip().replace('{', '(').replace('}', ')').replace('[', '(').replace(']', ')')
    print(int(eval(s)))

3. Solution2

1、思路

  1. 用兩個棧分別儲存數字和運算子;
  2. 如果當前運算子優先順序高於棧頂運算子優先順序,則將運算子入棧;反之,從數字棧中彈出兩個數,從運算子棧中彈出棧頂運算子,進行計算,數字棧壓入結果,符號棧壓入當前運算子。重複該操作直到不滿足條件。
  3. 出現左括號,則直接壓入;出現右括號,則從數字棧中彈出兩個數,從運算子棧中彈出棧頂運算子,進行計算,數字棧壓入運算結果。

細節: 如何判斷'+'或'-'是加減還是正負?
用一個變數來判斷:數字和運算子是交替出現的(括號的出現不會影響這種交替關係)。

import sys

if sys.platform != "linux":
    file_in = open("input/HJ50.txt")
    sys.stdin = file_in


def do_calc(st, so):
    b = st.pop()
    a = st.pop()

    op = so.pop()
    if op == '+':
        st.append(a + b)
    elif op == '-':
        st.append(a - b)
    elif op == '*':
        st.append(a * b)
    elif op == '/':
        st.append(a / b)


def cmp_prior(c1, c2):
    """比較兩個運算子的優先順序, c1 是否 大於 c2"""
    if c1 == '(':
        return False
    elif (c1 == '+' or c1 == '-') and (c2 == '*' or c2 == '/'):
        return False
    return True


def solve(s):
    st = list()  # 運算元棧
    so = list()  # 運算子棧
    so.append('(')
    s += ')'

    next_is_op = False
    i = 0
    while i < len(s):
        if s[i] in ('{', '[', '('):
            so.append('(')
        elif s[i] in ('}', ']', ')'):
            while so[-1] != '(':
                do_calc(st, so)
            so.pop()  # '('
        elif next_is_op:
            while cmp_prior(so[-1], s[i]):
                do_calc(st, so)
            so.append(s[i])
            next_is_op = False
        else:
            j = i  # 數字起點
            if s[j] == '-' or s[j] == '+':
                i += 1
            while s[i] not in "+-*/)]}":  # 找數字終點
                i += 1
            st.append(int(s[j: i]))  # 數字轉換
            i -= 1  # 抵消後面的 i 自增
            next_is_op = True  # 數字擷取完了,後面是運算子
        i += 1
    print(int(st[-1]))


for line in sys.stdin:
    s = line.strip()
    solve(s)

4. 拓展

相關的LeetCode 題目
LC150 字尾表示式求值、LC224 基本計算器