[프로그래머스] 뉴스 클러스터링

해시, 문자열


이 문제는 문자열을 잘 파싱해서 해시를 통해 교집합, 합집합의 개수를 세어주는 문제이다.

  1. 대문자 → 소문자
  2. dictionary 생성하여 확장된 자카드 집합을 만족시킨다.
  3. 교집합과 합집합을 주어진 규칙에 따라 구한다.

이 문제에서 새로 배운 내용이 있어서 포스팅 한다.

Counter는 딕셔너리 상위 호환이다. 이를 이용해서 문제를 해결할 수 있다. 유용하게 써보자

구현 1


def create_dict(string):
    str_dict = dict()
    for i in range(len(string)-1):
        if not string[i].isalpha() or not string[i+1].isalpha():
            continue
        tmp = string[i:i+2]
        if tmp in str_dict:
            str_dict[tmp] += 1
        else:
            str_dict[tmp] = 1
    return str_dict

def get_lower(string):
    return string.lower()

def get_union_intersection(a_dict, b_dict):
    union, intersection = 0, 0
    for key, value in a_dict.items():
        if key in b_dict:               # a, b 둘 다 존재해
            intersection += min(a_dict[key], b_dict[key])
            union += max(a_dict[key], b_dict[key])
        else:
            union += a_dict[key]            # a 에만 존재해
    for key, value in b_dict.items():
        if key not in a_dict:               # b 에만 존재해
            union += b_dict[key]
    return union, intersection

def solution(str1, str2):
    a = get_lower(str1)
    b = get_lower(str2)
    a_dict = create_dict(a)
    b_dict = create_dict(b)
    union, intersection = get_union_intersection(a_dict, b_dict)
    if union == 0:
        answer = 1
    else:
        answer = intersection / union
    return int(answer * 65536)

구현 2


딕셔너리 직접 조종하는 것 보다 쉽게 구현할 수 있다는 점을 배움

from collections import Counter

def create_dict(string):
    tmp = []
    for i in range(len(string)-1):
        if not string[i].isalpha() or not string[i+1].isalpha():
            continue
        tmp.append(string[i:i+2])
    return Counter(tmp)