[Python] 프로그래머스 - Level2 - [1차] 뉴스 클러스터링

강주형·2022년 8월 25일
0

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

2018 KAKAO BLIND RECRUITMENT

from collections import Counter

def solution(str1, str2):
    s1 = [ str1.lower()[i:i+2] for i in range(len(str1)-1) ]
    s2 = [ str2.lower()[i:i+2] for i in range(len(str2)-1) ]
    s1_clear = [s for s in s1 if s.isalpha()]
    s2_clear = [s for s in s2 if s.isalpha()]
    union = 0
    intersection = 0
    c1 = Counter(s1_clear)
    c2 = Counter(s2_clear)
    for s in set(s1_clear + s2_clear):    
        try: # s가 둘 다 있으면
            union += max(c1[s], c2[s])
            intersection += min(c1[s], c2[s])
        except: # s가 한 쪽이라도 없으면
            if s in c1:
                union += c1[s]
            else:
                union += c2[s]
    try:
        return int(intersection/union*65536)
    except:
        return 65536
  1. List Comprehension으로 2글자씩 자른 소문자를 s1, s2에 저장
  2. s1과 s2에서 isalpha()를 이용해서 영어인 것만 s1_clear, s2_clear에 저장
  3. s1_clear와 s2_clear의 Counter 객체 저장 (각 문자와 그 문자의 빈도가 저장)
  4. 두 Counter 객체를 합친 것의 집합을 반복문을 돌림
  5. 둘 다 있으면 try 동작, 한 쪽만 있으면 except 동작
  6. 만약 0으로 나누는 상황이 나오면 except의 return 동작

차근차근해보니까 풀렸다.
처음에 정규표현식으로 시도했는데 isalpha()를 사용해도 간단할 것 같았음


타인 코드

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)

set()끼리 %, |를 사용한 아이디어가 신선했다.
이렇게 하니까 count() 함수로 쉽게 계산이 되네
하나 알아간다!

profile
Statistics & Data Science

0개의 댓글