Covenant



채용이란 개인과 기업 모두 꿈의 시작이겠죠?
Source. 카카오가 신입 개발자 크루를 맞이하는 법


📖 뉴스 클러스터링 문제 확인




✏️ 문제 해결방법


  • 백준 450문제를 풀었지만... mset은 이 문제를 풀면서 처음 사용해봤습니다. 물론 꼭 mset을 사용하지 않아도 주의해서 구현하면 됩니다.
  • 자카드 유사도는 문제에서 잘 설명되어 있습니다. 그대로 구현을 하면 됩니다.
  • if len(s1_l) == 0 and len(s2_l) == 0: 를 통해서 A와 B집합이 공집합일 때 J(A, B) = 1을 처리합니다.
  • 단순히 합집합 원소의 갯수를 교집합 원소의 갯수로 나누면 즉, len(list((mset_s1 & mset_s2)))로 구현하면 안됩니다.
    • 반례: str1 = "AA1+AA1", str2 = "AAAA12" 인 경우에 mset_s1 = Counter({'AA': 2}), mset_s2 = Counter({'AA': 3}), 즉 1/1 * 65536 = 65536이 나옵니다.
    • 2/3 * 65536 = 43690이 나오도록 .elements()을 사용해야 합니다.


⭕ 최종 풀이 1

import re
from collections import Counter as mset

p = re.compile("[A-Z]{2}")

def setCollector(s):
    s_l = []
    for i in range(len(s)-1):
        if p.match(s[i:i+2]):
            s_l.append(s[i:i+2])
    return s_l


def solution(str1, str2):
    s1_l = setCollector(str1.upper())
    s2_l = setCollector(str2.upper())

    if len(s1_l) == 0 and len(s2_l) == 0:
        return 65536

    mset_s1 = mset(s1_l)
    mset_s2 = mset(s2_l)

    interSetLen = len(list((mset_s1 & mset_s2).elements()))
    unionSetLen = len(list((mset_s1 | mset_s2).elements()))

    return int(interSetLen / unionSetLen *65536)


⭕ 최종 풀이 2

import re
from collections import Counter as mset


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

    if len(s1_l) == 0 and len(s2_l) == 0:
        return 65536

    mset_s1 = mset(s1_l)
    mset_s2 = mset(s2_l)

    interSetLen = len(list((mset_s1 & mset_s2).elements()))
    unionSetLen = len(list((mset_s1 | mset_s2).elements()))

    return int(interSetLen / unionSetLen *65536)
  • re.findall('[^a-zA-Z]+', str1[i:i + 2]) 을 사용하면 풀이 1의 setCollector를 사용하지 않아도 됩니다.