プログラマLv 2式の最大化


https://programmers.co.kr/learn/courses/30/lessons/67257
問題を簡単に要約すると、0または999以下の数値と+、-、*の3つの演算子からなる3~100文字の文字列が入力されます.
ここで、演算子優先度を任意に変更して計算する場合、結果値の終端値が最大となる場合を求める.
「100-200*300-500+20」と入力した場合、出力60420.
また、「50*6-3*2」と入力すると、300を出力する必要があります.

に答える


まず考えられるのは,演算子の優先度を変えて直接計算する方法である.3つの演算子しかなく、6つのケースしかありません.
expression = ["*+-", "*-+", "+-*", "+*-", "-*+", "-+*"]
と書いて使いたかったのですがbacktrackingを使えば良さそうなのでbacktrackingで書きました;
演算子の優先度を決定できる関数を作成します.この関数では、すべての優先度が決定されたときに、優先度で計算された関数を呼び出して結果値を処理します.
演算子の優先度が決定されているため、式は最も優先度の高い演算子に基づいて分割され、再帰的に呼び出されるように計算されます.あまり良いコードではないような気がしますが、なんとかなりました.この時にまた家に帰るのは便利ですね.
check = [0, 0, 0]
exp = {0:"*", 1:"+", 2:"-"}
answer = 0
def solution(expression):
    prioritize(0, "", expression)
    return answer

def prioritize(n, ex, expression): #연산자 우선순위 정하기
    global answer
    if n == 3:
        result = abs(calculate(ex, expression))
        if answer < result:
            answer = result
        return
            
    for i in range(3):
        if check[i] == 0:
            check[i] = 1
            prioritize(n+1, ex+exp[i], expression)
            check[i] = 0
            
def calculate(ex, expression):	#계산하기
    if ex == "":
        return int(expression)
    
    splited = expression.split(ex[0])
    result = calculate(ex[1:], splited[0]) 
    for s in splited[1:]:
        if ex[0] == "*":
            result *= calculate(ex[1:], s)
        elif ex[0] == "+":
            result += calculate(ex[1:], s)
        elif ex[0] == "-":
            result -= calculate(ex[1:], s)
    return result