티스토리 뷰

https://school.programmers.co.kr/learn/courses/30/lessons/67257

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


1. 접근 방식

  • 연산자 우선순위는 expression 문자열에 있는 연산자 간 순열로 표현하자.

예를 들어 expression이 "50*6-3*2"이라면 여기에는 '*', '-' 2개의 연산자가 존재한다. 그럼 이 2개의 연산자로 순열을 구하면 [ ('-', '*'), ('*', '-') ] 이러하다. 첫 번째는 -가 우선순위가 높을 때이고, 두 번째는 *이 우선순위가 높을 때를 나타내는 각각의 우선순위 케이스이다. 생성된 순열 내 모든 케이스에 대해 계산을 해보고, 그중 가장 최대값을 알아내면 된다.

 

  • expression 문자열을 ['50', '*', '6', '-', '3', '*', '2']와 같은 리스트로 바꾸자.

expression 문자열을 그대로 사용하려면 * 연산자 앞뒤로 얼만큼 떨어진 곳까지가 숫자인지를 찾아내야 하기 때문에 번거롭다. 즉, * 연산자 위치가 2일 때 앞의 피연산자 50의 위치를 파악하기 위해선 (1) 인덱스가 0이 되거나 (2) 또 다른 연산자가 나올 때까지 계속 -1 해야 한다.

따라서 연산자의 앞뒤 숫자를 편하게 알아낼 수 있도록 리스트로 바꾸자. 이때 바로 list(expression)할 경우, [ '5', '0', '*', '6' ...] 처럼 50이라는 하나의 숫자가 5와 0으로 쪼개어진다. 이는 문자열과 똑같은 불편함이 발생하므로, [ '50', '*', '6' ... ]과 같은 형태로 리스트를 만들어야 한다.

 

 

2. 정답 코드

def make_list(expr, ops):
    result = []
    n = ''
    for x in expr:
        if x in ops:
            result.append(n)
            result.append(x)
            n = ''
        else:
            n += x
    result.append(n)
    return result

def solution(expression):
    import re
    from itertools import permutations
    
    ops = set(re.sub('[0-9]', '', expression)) # 연산자 뽑아내기
    perms = permutations(list(ops)) # 연산자 우선순위 종류
    
    expr = make_list(expression, ops) # ex) ['50', '*', '6', '-', '3', '*', '2']

    answer = 0
    for perm in perms:
        result = expr.copy()
        
        for op in perm:
            cnt = result.count(op)
            
            for _ in range(cnt):
                index = result.index(op)
                result[index-1] = eval(f'{result[index-1]} {result[index]} {result[index+1]}')
                result.pop(index)
                result.pop(index)
                
        answer = max(answer, abs(result[0]))
        
    return answer
728x90