[programmers] 뉴스 클러스터링

wonyu·2022년 2월 19일
0

algorithm

목록 보기
22/25

문제 링크

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

풀이 방법

처음에는 set을 사용해서 합집합과 교집합을 계산하려고 했으나 다중집합에 대한 조건이 있어서 어떤 자료형을 사용할지 고민했다. 그러다가 중복된 원소의 개수를 세고 인덱싱을 좀 더 빠르게 하기 위해 딕셔너리를 사용하기로 결정했다.

우선 str1, str2에 대해 각각 2글자씩 끊어서 딕셔너리에 저장한 뒤 딕셔너리를 하나씩 순회하며 교집합과 합집합을 저장한 뒤, 조건에 따라 계산한 값(int((교집합 / 합집합) * 65536))을 리턴하고자 했다.

문제를 풀면서 유의해야 했던 부분은 2글자가 알파벳으로 구성된 게 맞는지 확인하는 것, 대소문자 구분이 없으므로 딕셔너리에 저장할 때 소문자로 변환했던 것, 두 번째 딕셔너리를 순회할 때는 첫 번째 딕셔너리에서 계산하지 않은 원소만 계산하는 것, 그리고 마지막으로 교집합과 합집합이 둘 다 0일 때만 두 값을 1로 하여 계산하는 것이었다.

코드

def break_str(str0):
    """
    2글자씩 끊어서 딕셔너리에 담는 함수
    """
    dic = {}
    for i in range(len(str0) - 1):
        if str0[i:i + 2].isalpha():
            tmp = str0[i:i + 2].lower()
            if tmp in dic:
                dic[tmp] += 1
            else:
                dic[tmp] = 1
    return dic


def solution(str1, str2):
    dict1 = break_str(str1)
    dict2 = break_str(str2)
    union, inter = 0, 0

    # dict1부터 순회하며 dict2에도 있는 값이면 더 큰 값을 합집합에, 더 작은 값을 교집합에 카운트
    for key, value in dict1.items():
        if key in dict2:
            union += max(dict1[key], dict2[key])
            inter += min(dict1[key], dict2[key])
            dict2[key] = 0
        else:
            union += dict1[key]

    # dict2 : dict1에 없는 값일 경우에만 합집합에 카운트
    for key, value in dict2.items():
        if value != 0:
            union += dict2[key]

    # '둘 다' 0일 때만 1로 계산한 값 리턴
    if not union and not inter:
        return 65536
    return int((inter / union) * 65536)

0개의 댓글