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

joon_1592·2022년 1월 19일

알고리즘

목록 보기
19/51

1. 나의 첫 풀이

  1. 두 집합 A, B 구하기
    1.1 문자열을 소문자로 바꾼다 (lower())
    2.2 두글자씩 끊긴 문자열의 개수를 계산한다. 이때 알파벳만 인정 (isalpha())
  2. 자카드 유사도 구하기
    2.1 교집합 원소 개수 구하기
    2.2 합집합 원소 개수 구하기
    2.3 유사도 반환
    3 65536을 곱하고 소수부분 버리기 (int())
def J_sim(A, B):
    if len(A) == 0 and len(B) == 0:
        return 1
    
    intersect, union = {}, {}
    for a in A.keys():
        if B.get(a, 0) > 0:
            intersect[a] = min(A[a], B[a])
        union[a] = max(A.get(a, 0), B.get(a, 0))
    for b in B.keys():
        union[b] = max(A.get(b, 0), B.get(b, 0))
    #print(intersect)
    #print(union)
    
    n_intersect, n_union = 0, 0
    for k in intersect.keys():
        n_intersect += intersect[k]
    for k in union.keys():
        n_union += union[k]

    return n_intersect / n_union

def solution(str1, str2):
    answer = 0
    A, B = {}, {}
    str1 = str1.lower()
    str2 = str2.lower()
    
    for i in range(len(str1)-1):
        sub_str = str1[i:i+2]
        if sub_str.isalpha():
            A[sub_str] = A.get(sub_str, 0) + 1
    
    for i in range(len(str2)-1):
        sub_str = str2[i:i+2]
        if sub_str.isalpha():
            B[sub_str] = B.get(sub_str, 0) + 1
    #print(A)
    #print(B)
    answer = int(65536 * J_sim(A, B))
    return answer

2. 다른사람의 풀이

  1. 정규표현식으로 문자열 거르기 re.findall('[^a-zA-Z]+')
    1.1 알파벳만 거르면 되는데 정규표현식은 too much라고 생각한다.
    1.2 실제 코테에서도 import re가 가능한지 의문
  2. 교집합, 합집합 연산을 set의 &, | 연산으로 해결
    2.1 집합에서 합집합, 교집합 연산은 O(n)이므로 코드가 간결하다
    2.2 union(), intersection()을 활용해볼까?
  3. A, B집합은 처음엔 리스트로, 나중에 집합처럼 구한다
    3.1 굳이 딕셔너리로 하지 않고도 가능한 풀이
  4. Counter를 활용하여 개수 세기
    4.1 실제 코딩에서 자주 사용되는 Counter를 코테에서 활용하기
    4.2 실제 코테에서도 컬렉션을 사용할 수 있는가?
profile
공부용 벨로그

0개의 댓글