본문 바로가기

알고리즘/프로그래머스

2018 KAKAO BLIND RECRUITMENT- 뉴스 클러스터링, 파이썬

문제

프로그래머스 문제 링크

문제 파악

  • 집합 A와 집합 B가 모두 공집합일 경우에는 나눗셈이 정의되지 않으니 따로 J(A, B) = 1로 정의
  • 다중집합 A = {1, 1, 2, 2, 3}, 다중집합 B = {1, 2, 2, 4, 5}라고 하면, 교집합 A ∩ B = {1, 2, 2}, 합집합 A ∪ B = {1, 1, 2, 2, 3, 4, 5}가 되므로, J(A, B) = 3/7, 약 0.42
  • 두 글자씩 끊어서 다중집합의 원소로 만든다. 이때 영문자로 된 글자 쌍만 유효하고, 기타 공백이나 숫자, 특수 문자가 들어있는 경우는 그 글자 쌍을 버린다. 예를 들어 "ab+"가 입력으로 들어오면, "ab"만 다중집합의 원소로 삼고, "b+"는 버린다
  • 대문자와 소문자의 차이는 무시
  • 자카드 유사도를 구하고 65536을 곱한 후에 소수점 아래를 버리고 정수부만 출력

주의해야할 사항

  • 문제는 어려운 편은 아니나 주의해서 처리해야 할 부분은 교집합을 구하는 부분
  • 교집합이 중복을 허용하기 때문에 이 부분을 코드로 처리해주는 것이 관건이다.

코드

def str_to_arr(string) :
    string = string.lower()
    arr = []
    for i in range(len(string)-1) :
        if not ('a'<= string[i] <= 'z' and 'a'<= string[i+1] <= 'z') :
            continue
        arr.append(string[i:i+2])
    return arr

def solution(str1, str2):
    arr1 = str_to_arr(str1)
    arr2 = str_to_arr(str2)
    n1 = 0
    n2 = 0
    dic = {}
    for s in arr1 :
        if s in arr2 and s not in dic:
            dic[s] = min(arr1.count(s), arr2.count(s))
    n1 = sum(dic.values())
    n2 = len(arr1) + len(arr2) - n1

    if not arr1 and not arr2:
        return 65536
    else :
        return int(n1/n2 * 65536)

개선

  • 다른 깔끔한 풀이보다 지저분한 편. 조금 더 간소화시키고 직관적으로 바꿀 필요가 있다.