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

.·2022년 4월 5일
0

문제 링크 - https://programmers.co.kr/learn/courses/30/lessons/17677


나의 풀이

import math
def solution(str1, str2):
    s1 = str1.lower()
    s2 = str2.lower()
    s1_list = []
    s2_list = []
    if s1 == s2:
        return 65536
    else:
        for i in range(len(s1)-1):
            s1_list.append(s1[i:i+2])
        for i in range(len(s2)-1):
            s2_list.append(s2[i:i+2])
    
    s1_list_new = []
    s2_list_new = []
    for i in s1_list:
        if i.isalpha():
            s1_list_new.append(i)
    for i in s2_list:
        if i.isalpha():
            s2_list_new.append(i)
    
    inter = []
    s2_inter = s2_list_new.copy()

    for i in s1_list_new:
        if i in s2_inter:
            inter.append(i)
            s2_inter.remove(i) # remove를 해주지 않으면 [a,a,a,b,b], [a,a,b,b,b]인 경우에 i 가 첫번째 리스트의 3번째 a 일 때에도 교집합에 추가가 됨
    
    # 다중 집합의 합집합
    s1_list_temp = s1_list_new.copy()
    s1_list_result = s1_list_new.copy()
    for i in s2_list_new:
        if i not in s1_list_temp:
            s1_list_result.append(i)
        else:
            s1_list_temp.remove(i)
            
    union = s1_list_result
    
    if len(inter) == 0 and len(union) == 0: # 두 집합 모두 공집합일 때 교집합과 합집합 모두 공집합이므로 and를 써야함
        return 65536                        # 만약 or로 한다면 교집합이 공집합이고 합집합은 공집합이 아니라도 65536을 return하므로 안됨
    else:                                   # 교집합이 공집합이고 합집합이 공집합이 아닐때는 0을 return해야함
        return math.trunc(len(inter)/len(union) * 65536)
  • 일단 문자열을 두개씩 다 잘라서 리스트에 넣고 알파벳이 아닌 것들은 제거한 후 교집합과 합집합을 구했다.
  • 하지만 합집합에서 a = [1,2,2,3,4,5], b = [1,1,2,3,4,6]와 같이 중복된 값들이 들어있는 것들은 구하는데 어려움이 있어 다른 블로그를 참고하였다.
  • 또 계속 테스트케이스 두 개가 틀렸다고 나와 찾아보니 교집합 부분에서 remove를 해주지 않아서 그랬다.
  • 코드가 너무 지저분해서 다음에 보면 나도 헷갈릴 듯


조금 더 깔끔한 버전

import math
def solution(str1, str2):
    if str1 == str2:
        return 65536
    else:
        s1 = lm(str1)
        s2 = lm(str2)
    
    # 교집합
    inter = []
    s2_inter = s2.copy()
    for i in s1:
        if i in s2_inter:
            inter.append(i)
            s2_inter.remove(i) # remove를 해주지 않으면 [a,a,a,b,b], [a,a,b,b,b]인 경우에 i 가 첫번째 리스트의 3번째 a 일 때에도 교집합에 추가가 됨
    
    # 다중 집합의 합집합
    s1_list_temp = s1.copy()
    s1_list_result = s1.copy()
    for i in s2:
        if i not in s1_list_temp:
            s1_list_result.append(i)
        else:
            s1_list_temp.remove(i)
            
    union = s1_list_result
    
    if len(inter) == 0 and len(union) == 0: # 두 집합 모두 공집합일 때 교집합과 합집합 모두 공집합이므로 and를 써야함
        return 65536                        # 만약 or로 한다면 교집합이 공집합이고 합집합은 공집합이 아니라도 65536을 return하므로 안됨
    else:                                   # 교집합이 공집합이고 합집합이 공집합이 아닐때는 0을 return해야함
        return math.trunc(len(inter)/len(union) * 65536)

def lm(s):
    s1 = []
    s = s.lower()
    for i in range(len(s)-1):
        if s[i:i+2].isalpha():
            s1.append(s[i:i+2])
    return s1


다른 사람의 풀이

import math


def solution(str1, str2):
    s1 = make_2_word(str1)
    s2 = make_2_word(str2)
    print(s1,s2)
    if s1 == [] and s2 == []:
        return 65536

    s1_copy = s1.copy()
    s2_copy = s2.copy()

    # 교집합
    inter = []
    for i in s1:
        if i in s2_copy:
            inter.append(i)
            s1_copy.remove(i)
            s2_copy.remove(i)


    # 합집합
    union = inter + s1_copy + s2_copy


    answer = math.floor((len(inter) / len(union)) * 65536)
    return answer


def make_2_word(s):
    s = s.upper()
    a = []
    for i in range(len(s) - 1):
        if s[i:i + 2].isalpha():
            a.append(s[i:i + 2])
    return a

교집합을 구하면서 겹치는 애들은 remove를 해줬기 때문에 합집합은 교집합 + 남은 애들을 하면 된다.



느낀점

  • 비슷한 기능을 하는 것들은 함수로 만들어서 활용하기
  • 코드를 처음 짤 때부터 깔끔하게 짜도록 노력하기!!!!!!!

0개의 댓글