[알고리즘] 파이썬 Counter 객체

O(logn)·2024년 3월 3일
0

코테 준비

목록 보기
1/3
post-thumbnail

사진: UnsplashLena Polishko

목차

  • 문제 소개
  • 풀이 1(첫 풀이)
  • 풀이 2(프로그래머스 모범 답안)

문제: 누가 가면을 잃어버렸는가?

문제 설명

매년 개최되는 화려한 가면무도회에 수많은 참가자들이 초대되었습니다. 모든 참가자들은 독특한 가면을 쓰고 무도회에 참석하였지만, 행사가 끝난 후 한 명의 참가자만이 가면을 잃어버렸습니다.

무도회에 참가한 사람들의 이름이 담긴 배열 attendees와 무도회가 끝난 후 가면을 찾은 사람들의 이름이 담긴 배열 masksFound가 주어질 때, 가면을 찾지 못한 참가자의 이름을 반환하는 solution 함수를 작성해주세요.

제한사항

  • 무도회 참가자의 수는 1명 이상 100,000명 이하입니다.
  • masksFound의 길이는 attendees의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

입출력 예

attendeesmasksFoundreturn
["alice", "bob", "claire"]["claire", "alice"]"bob"
["diana", "elena", "fiona", "gina", "hannah"]["elena", "hannah", "diana", "fiona"]"gina"
["ivy", "jess", "ivy", "kate"]["kate", "jess", "ivy"]"ivy"

입출력 예 설명

  • 예제 #1: "bob"은 참가자 명단에는 있지만, 가면을 찾은 사람들의 명단에는 없기 때문에 가면을 찾지 못했습니다.
  • 예제 #2: "gina"는 참가자 명단에는 있지만, 가면을 찾은 사람들의 명단에는 없기 때문에 가면을 찾지 못했습니다.
  • 예제 #3: "ivy"는 참가자 명단에 두 명이 있지만, 가면을 찾은 사람들의 명단에는 한 명밖에 없기 때문에 한 명은 가면을 찾지 못했습니다.

풀이 1

  • 딕셔너리 두 개를 만들어 value 비교하기
def solution(attendees, masksFound):
    # attendees를 key로 하고 value는 모두 0인 딕셔너리 생성
    attendees_dict = {}
    masksFound_dict = {}
    lostMaskOwner = ""
    
    for attendee in attendees:
        if attendee not in attendees_dict:
            attendees_dict[attendee] = 1
            masksFound_dict[attendee] = 0  # 전체 참여자의 이름을 key로 하고, masksFound에 등장하는 이름의 개수를 value로 하는 masksFound_dict 정의
        else:
            attendees_dict[attendee] += 1

    # masksFound에 있는 이름은 masksFound_dict에서 value를 1씩 올린다.
    for found in masksFound:
        masksFound_dict[found] += 1

    # masksFound_dict에서 value가 attendees_dict의 value -1인 key를 lostMaskOwner에 저장한다.
    for attendee in attendees:
        if attendees_dict[attendee] - 1 == masksFound_dict[attendee]:
            lostMaskOwner = attendee
    return lostMaskOwner

풀이 2

from collections import Counter

def solution(attendees, masksFound):
    # attendees 배열과 masksFound 배열의 Counter 객체를 생성
    # Counter 객체를 사용하여 attendees와 masksFound의 차이를 계산
    # 차이에서 나온 결과(가면을 찾지 못한 참가자)의 키(keys)를 리스트로 변환
    # 첫 번째 요소를 반환하여 가면을 잃어버린 참가자의 이름을 찾음
    return list((Counter(attendees) - Counter(masksFound)).keys())[0]

collections 모듈에서 제공하는Counter 객체를 사용하면 손쉽게 풀 수 있다.
Counter객체는 다음과 같이 사용할 수 있다.

>>> c = Counter("abcde") #문자열을 넣어주면 문자요소로 Counting
>>> c
Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1})

>>> c = Counter({'red':4,'blue':2}) #dict객체를 넣어주면 dict 그대로 count를 만들어준다
>>> c
Counter({'red': 4, 'blue': 2})

위와 같이 문자열이나 리스트 등 iterable한 데이터를 입력하면 자동으로 요소의 개수를 세어 dictionary와 유사한 JSON 형식의 자료로 변환해준다. 아래와 같이 dictionary를 Counter로 변환하여 사용하는 이유는 Counter의 강력한 연산 기능 때문이다.

c1 = Counter(['a', 'b', 'c', 'a', 'b', 'b'])
c2 = Counter('alphabet')

# Counter 객체 더하기
print(c1 + c2)

# Counter 객체 빼기
print(c1 - c2)

# Counter 객체의 교집합
print(c1 & c2)

# Counter 객체의 합집합
print(c1 | c2)

느낀 점

Python이 C나 C++, Java에 비해 실행 속도 면에서 불리하지만 라이브러리의 다양성만큼은 큰 경쟁력인 것 같다. 깔끔한 풀이와 간단 명료한 로직도 중요하지만 다양한 라이브러리를 적절하게 활용하는 능력도 못지 않게 중요한 듯하다.

profile
聞一知十

0개의 댓글

관련 채용 정보