Coding Test/programmers

[Python] 파이썬 프로그래머스 뉴스 클러스터링

파송송 2023. 3. 10. 19:44
728x90

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


나의 풀이

  • 2개의 집합에 자카드 유사도를 구하는 문제
  • A = {1, 2, 3}, B={2, 3, 4} 일 때 교집합 = {2, 3}, 합집합 = {1, 2, 3, 4}이다.
  • 이때 자카드 유사도는 2/4로 0.5가 된다.

입력 형식을 잘 참고하여 문제를 풀어야함

  • 2 글자씩 잘라서 집합에 넣음
  • 원소에 영문자만 있어야 함 (영문자 제외 다를 문자가 있다면 그 원소는 삭제)
  • 대소문자 구분 안 함

1. 문자열을 소문자로 변환뒤 영문자로 구성된 원소만 list에 담는다.

2. 집합의 교집합을 구해 count 하여 min 값을 누적 합한다.

3. 두 집합 길이을 더하고 누적합값을 빼준다.

import re

def solution(str1, str2):
    str1, str2 = str1.lower(), str2.lower()
    a, b = list(), list()
    for  i  in range(1, len(str1)):
        if re.compile('[a-z]').match(str1[i - 1]) and re.compile('[a-z]').match(str1[i]):
            a.append(str1[i - 1] + str1[i])

    for  i  in range(1, len(str2)):
        if re.compile('[a-z]').match(str2[i - 1]) and re.compile('[a-z]').match(str2[i]):
            b.append(str2[i - 1] + str2[i])
    intersec = list(set(a)&set(b))
    uni_sum= 0
    for i in intersec:
        min_u = min(a.count(i), b.count(i))
        uni_sum += min_u
    intersec_sum = len(a) + len(b) - uni_sum
    if intersec_sum == 0:
        ans = 1
    else:
        ans = uni_sum / intersec_sum

    return int(ans * 65536)


다른 사람의 풀이

set과 max, min을 이용한 풀이

중복 제거가 아니기 때문에 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)

728x90