[프로그래머스] 뉴스 클러스터링 풀이 _ 2018 KAKAO BLIND RECRUITMENT



1. 문제

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

2. 풀이

2.1. dictionary를 이용한 풀이

  • 풀이에 해설에 대하여 주석으로 남겨보았습니다.
import math
def solution(str1, str2):
    dic1 = {};     dic2 = {};
    str_arr = [str1, str2]
    dic_arr = [dic1, dic2]
    for i in range(2):
        for j in range(1, len(str_arr[i])):             # 2글자씩 끊어서 만든 글자를 딕셔너리의 key에 넣고 개수만큼 value로 지정합니다.
            if str_arr[i][j - 1:j + 1].isalpha():       # 알파벳 검사
                key = str_arr[i][j - 1:j + 1].lower()   # 소문자로 치환
                if key not in dic_arr[i]:               # 값을 추가해준다. 
                    dic_arr[i][key] = 1
                else:
                    dic_arr[i][key] += 1

    same = 0
    total = 0
    for key in dic1:                                    # dic1의 key를 모두 살펴보면서 공통 요소를 same에 체크
        if key in dic2:                                 # dic1의 key가 dic2에 없거나, dic2의 key가 dic1에 없는 경우 추가로 total에 체크
            same += min(dic1[key], dic2[key])
            total += max(dic1[key], dic2[key])
        else:
            total += dic1[key]

    for key in dic2:
        if key not in dic1:
            total += dic2[key]
    if total == 0:
        return 65536
    return math.floor((same / total) * 65536)

2.2. 집합, 배열을 이용한 숏코딩

  • 프로그래머스에 정리된 효과적인 풀이방법입니다.
  • 2개의 문자열이 모두 알파벳으로 이뤄진 경우 소문자로 변경하여 배열에 넣습니다.
  • 교집합, 합집합을 set을 이용하여 공통 인자만 남깁니다.
  • 위의 set에서 구한 공통 인자를 배열을 탐색하면서 문자열의 개수를 모두 더해줍니다.
import re
import math

def solution(str1, str2):
    str1 = [str1[i:i+2].lower() for i in range(0, len(str1)-1) if not re.findall('[^a-zA-Z]+', str1[i:i+2])]
    str2 = [str2[i:i+2].lower() for i in range(0, len(str2)-1) if not re.findall('[^a-zA-Z]+', str2[i:i+2])]

    gyo = set(str1) & set(str2)
    hap = set(str1) | set(str2)

    if len(hap) == 0 :
        return 65536

    gyo_sum = sum([min(str1.count(gg), str2.count(gg)) for gg in gyo])
    hap_sum = sum([max(str1.count(hh), str2.count(hh)) for hh in hap])

    return math.floor((gyo_sum/hap_sum)*65536)