관리 메뉴

개발 블로그

[Programmers/파이썬] 프로그래머스(Lv.2) <튜플> 문제 풀이 본문

Algorithm

[Programmers/파이썬] 프로그래머스(Lv.2) <튜플> 문제 풀이

토산인 2023. 2. 25. 02:16

문제 설명

셀수있는 수량의 순서있는 열거 또는 어떤 순서를 따르는 요소들의 모음을 튜플(tuple)이라고 합니다. n개의 요소를 가진 튜플을 n-튜플(n-tuple)이라고 하며, 다음과 같이 표현할 수 있습니다.

  • (a1, a2, a3, ..., an)

튜플은 다음과 같은 성질을 가지고 있습니다.

  1. 중복된 원소가 있을 수 있습니다. ex : (2, 3, 1, 2)
  2. 원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex : (1, 2, 3) ≠ (1, 3, 2)
  3. 튜플의 원소 개수는 유한합니다.

원소의 개수가 n개이고, 중복되는 원소가 없는 튜플 (a1, a2, a3, ..., an)이 주어질 때(단, a1, a2, ..., an은 자연수), 이는 다음과 같이 집합 기호 '{', '}'를 이용해 표현할 수 있습니다.

  • {{a1}, {a1, a2}, {a1, a2, a3}, {a1, a2, a3, a4}, ... {a1, a2, a3, a4, ..., an}}

예를 들어 튜플이 (2, 1, 3, 4)인 경우 이는

  • {{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}}

와 같이 표현할 수 있습니다. 이때, 집합은 원소의 순서가 바뀌어도 상관없으므로

  • {{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}}
  • {{2, 1, 3, 4}, {2}, {2, 1, 3}, {2, 1}}
  • {{1, 2, 3}, {2, 1}, {1, 2, 4, 3}, {2}}

는 모두 같은 튜플 (2, 1, 3, 4)를 나타냅니다.

특정 튜플을 표현하는 집합이 담긴 문자열 s가 매개변수로 주어질 때, s가 표현하는 튜플을 배열에 담아 return 하도록 solution 함수를 완성해주세요.

[제한사항]

  • s의 길이는 5 이상 1,000,000 이하입니다.
  • s는 숫자와 '{', '}', ',' 로만 이루어져 있습니다.
  • 숫자가 0으로 시작하는 경우는 없습니다.
  • s는 항상 중복되는 원소가 없는 튜플을 올바르게 표현하고 있습니다.
  • s가 표현하는 튜플의 원소는 1 이상 100,000 이하인 자연수입니다.
  • return 하는 배열의 길이가 1 이상 500 이하인 경우만 입력으로 주어집니다.

 

 


문제 푸는데 걸린 시간

24분

 

사고 흐름과 총평

튜플을 집합으로 바꿀 때 튜플의 원소 순서대로 하나씩 추가해서 집합들을 만드는구나

-> 잠깐, 길이가 가장 긴 집합을 골라 해결하려고 했지만 비효율적이고 집합 내 순서가 없어 안했음

-> 튜플과 집합의 관계를 파악해보니, 튜플의 원소가 누적돼 집합에 추가된다는 것을 알고 원소의 개수로 해결

리스트, 딕셔너리를 활용한 문자열 활용 문제같다. 

 

문제 핵심과 알고리즘

리스트와 딕셔너리를 활용한 문자열 활용 문제

import collections

def solution(s):
    answer = []
    su = 0
    
    for i in s :
        if i.isdigit() :
            su=su*10+int(i)
        elif su != 0 :
            answer.append(su)
            su=0
    
    answer=collections.Counter(answer)
    
    return [int(i[0]) for i in answer.most_common()]

 

문제 풀면서 헤맸던 부분

1. 집합 문자열에서 숫자 추출

  연속적으로 나오는 숫자이면 *10+i 로 각 자리수를 크게 해주고, 숫자가 아닌 기호가 나오면 숫자가 끝났다는 말이므로 append하고 숫자를 초기화했다.

 => 정규표현식으로 해보자

 

2. Counter의 객체 return 

  Counter로 return하고 answer.keys()로 원소들을 추출했는데 빈도수대로 추출이 안되고 숫자가 정렬돼서 출력됐다. 자동완성으로 most_common() 함수를 발견했고 이 함수로 빈도수대로 원소를 추출했다.

 => Counter 개념 정확하게 잡기

 

 

다른 사람들 풀이 참고하며 배운 점

def solution(s):
    s = Counter(re.findall('\d+', s))
    
    return list(map(int, [k for k, v in sorted(s.items(), key=lambda x: x[1], reverse=True)]))

정규표현식 사용해 숫자만 추출하고 람다식을 사용해 빈도를 기준으로 정렬하고 key 값을 가져왔다

 

 

<개념 정리>

1. Counter 객체

import collections
 
list = ['Hello', 'HI', 'How', 'When', 'Where', 'Hello']
 
print(collections.Counter(list))

#Counter({'Hello': 2, 'HI': 1, 'How': 1, 'When': 1, 'Where': 1})

Counter 객체는 아이템에 대한 개수를 계산해 딕셔너리로 리턴한다. (key는 아이템 값, value에는 아이템 개수가 들어간다)

 

Counter의 함수

  • most_common(): 가장 빈도수가 높은 요소를 리스트로 추출한다
  • items(): 딕셔너리에 있는 key와 value 값을 쌍으로 return 
for key, value in ex_counter.items():
    print(key, ':' , value)

 

2. findall(pattern, text)

text에서 pattern과 일치하는 부분을 모두 찾아 return 한다.

자주 쓰이는 정규표현식 정리

/d 숫자 [0-9]    #0123456789
/D 숫자가 아닌 것 [^0-9]
/w 숫자와 문자 [a-zA-Z0-9]
/W 숫자와 문자가 아닌 것 [^a-zA-Z0-9]
/s 공백 [ \t\n\r\f\v]
/S 비공백 [^ \t\n\r\f\v]
. 하나의 모든 문자
* 0번 또는 최소 한 번 이상 
+ 최소 한 번 이상

https://nachwon.github.io/regular-expressions/

 

[Python 문법] 정규표현식 (Regular Expressions)

정규표현식에 대해 알아보고 Python으로 정규표현식을 사용하는 방법에 대해 알아본다.

nachwon.github.io

 

3. sorted(data, key 파라미터, reverse 파라미터): 람다식 활용한 정렬

sorted는 정렬된 새로운 리스트를 반환한다. 

  • key 옵션: 어떤 것을 기준으로 정렬할 것인가?
  • reverse 옵션: true면 내림차순, false면 오름차순