[프로그래머스] 튜플 (Level 2) 파이썬 풀이

2020. 11. 24. 21:15알고리즘

 

※사용언어 : 파이썬

 

▼ 문제 링크 ▼

https://programmers.co.kr/learn/courses/30/lessons/64065

 

코딩테스트 연습 - 튜플

"{{2},{2,1},{2,1,3},{2,1,3,4}}" [2, 1, 3, 4] "{{1,2,3},{2,1},{1,2,4,3},{2}}" [2, 1, 3, 4] "{{4,2,3},{3},{2,3,4,1},{2,3}}" [3, 2, 4, 1]

programmers.co.kr

 

 


 

 

문제 설명

해당 문제는 요소의 묶음이 주어졌을 때, 해당 묶음에 있는 요소들을 중복 값 없이 출력하라는 것이다. 

간단히 예시와 함께 문제 설명을 이어가도록 하겠다.
입출력 예 1번과 2번을 보겠다.

1번 : "{{2},{2,1},{2,1,3},{2,1,3,4}}"
2번 : "{{1,2,3},{2,1},{1,2,4,3},{2}}"

1번과 2번의 문자열은 다르지만 출력 결괏값은 같다
왜 이런 현상이 벌어질까?
2번 문자열("{{1,2,3},{2,1},{1,2,4,3},{2}}")을 부분집합의 관점으로 보면 {1,2,3} , {2,1} , {1,2,4,3} , {2}로 볼 수 있다. 
해당 부분집합을 집합 안에 있는 원소가 작은 수로 나열하면
{2} , {2,1} , {1,2,3} , {1,2,4,3} 이 된다.
{2} , {2,1} , {1,2,3} , {1,2,4,3} 는 1번 문자열과 완전히 같은 형태이다.
그래서 1번과 2번의 출력 값이 동일하다.

이 문제에서 중요한 것은 요소 묶음의 순서이다.
입출력 예 3번을 보면 입력값은 "{{20,111},{111}}"이고 출력 값은 [111, 20]이다.
3번 문자열 속 집합을 원소의 수가 적은 순으로 나열하면 
{111} , {20,111}이 된다.
여기서 {111}의 111이 결괏값에 들어가고 {20,111} 같은 경우 111이 이미 결과값에 들어가있다. 중복을 제거하기 때문에 20만 결과값에 들어가게 된다.
그래서 [111,20]이 출력되게 된다.

 

 

 


 

 

문제 풀이(with Python)

import re
def solution(s):
    string1=s[1:len(s)-1]
    flag=0
    num_list=[]
    for i in range(1,len(string1)):
        if(string1[i]=="}"):
            num=re.findall("\d+",string1[flag:i])
            num_list.append(list(map(int,num)))
            flag=i

    num_list.sort(key=lambda x: len(x))

    answer = []
    for a in range(0,len(num_list)):
        for b in range(0,len(num_list[a])):
            if not num_list[a][b] in answer:
                answer.append(num_list[a][b])
    return answer

 

입출력 예시 2번인 "{{1,2,3},{2,1},{1,2,4,3},{2}}"을 예를 들어 설명하도록 하겠다.

 

◇ import re ▶ re.findall을 사용하기 위해 import한다.

 

◇ string1=s[1:len(s)-1] ▶ 입력 문자열 앞에 있는 {와 제일 뒤에 있는 }를 없애는 코드

s="{{1,2,3},{2,1},{1,2,4,3},{2}}"이면 string1="{1,2,3},{2,1},{1,2,4,3},{2}"

 

◇ flag=0 ▶ { } 영역의 앞부분을 가리키는 변수

즉 {1,2,3} 에서 { 부분이 flag가 가리키는 곳이다.

 

◇ for i in range(1, len(string1)) ▶ string1에서 { } 영역을 찾아 { }안에 숫자만 뽑아내어 int로 형 변환을 하여 list에 저장

→ re.findall(~) ▶{ } 영역 안에서 숫자만 찾아내서 num에 list형태로 저장 (re.findall 설명)

→ num_list.append(list(map(int,num)) ▶ num이 list형태이므로 map을 사용하여 num안에 있는 요소들의 형을 int로 변환, 이때 map을 list로 묶은 이유는 map은 기본 반환형이 map object이기 때문이다. 그렇기 때문에 반드시 map은 리스트나 튜플 형태로 반환해야 한다. int형으로 반환된 num list를 num_list에 넣어준다.

num_list=[[1,2,3],[2,1],[1,2,4,3],[2]] 

 

◇ num_list.sort( ~ ) ▶ num_list에 들어간 num 리스트를 길이에 따라 오름차순으로 정렬한다.

num_list=[[1,2,3],[2,1],[1,2,4,3],[2]] 가 정렬이 되면 num_list=[[2],[2,1],[1,2,3],[1,2,4,3]] 으로 바뀌게 된다.

 

◇ for a ~~ answer.append( ~ ) : 이중 for문을 통해 num_list값에서 중복 값을 제외한 요소를 answer에다 넣는다.