새소식

Computer Science/코딩테스트 문제 풀이

[N시간만에 끝내는 Python 코딩테스트] 6편 2018 카카오 코딩테스트 5번 뉴스 클러스터링

  • -

https://school.programmers.co.kr/learn/courses/30/lessons/17677?language=python3

 

프로그래머스

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

programmers.co.kr

 

https://www.youtube.com/watch?v=YoPwLD9K-3Q&list=PLkfUwwo13dlUW9tPNXYnr-6EmYuUOvlko&index=6

 

 

import re를 잘쓰고 

예외 처리를 잘 하며 

헷갈리지 않고 실수 안하고 

추가되는 조건 잘 캐치해서 적용하면 충분히 할 수 있다. 

 

크게 

# 1. 영문자를 모두 대문자나 소문자로 통일한다. 

# 2. 영문자 2개씩 끊어서 집합에 넣을껀데 영문자가 아닌것이 포함된 문자는 넣지 않는다. 

예): {AAA} -> {AA, AA}가 되고 {AA2B} -> {AA}가 된다

# 3.  교집합과 합집합의 크기를 각각 구하고 자카드 유사도를 구해 65536을 곱해준다. 

- 3.1  중복되는 수를 추가 해준다. 

일반집합의 교집합이나 합집합은 중복을 허락하지 않는다. 

예를 들어 교집합이 {1,2,2}가 될 수 없다 {1,2}이어야 한다. 따라서 중복되는 수를 추가 해준다. 

# 4. 예외처리는 항상 까먹지 말고 

 


import re 

def solution(str1, str2): 
    
    # 예외 처리 
    if len(str1)<=1 and len(str2)<=1:
        return 65536
    
    # 1. 영문자를 통일 
    str1, str2 = str1.upper(), str2.upper()
    
    # 2. 2개씩 끊어서 집합에 넣기 
    str1List = []
    str2List = []
    
    pattern = re.compile(r'[A-Z]{2}')       # 오직 영문자에 대해서만 2개씩 
    
    for i in range(len(str1)-1):            # 문자열을 다 돌아 
        twoset=str1[i]+str1[i+1]
        if pattern.findall(twoset):         # 2개 짜리가 영문자로만 이루어져있으면 
            str1List.append(twoset)         # 리스트에 넣기 
    
    for i in range(len(str2)-1):
        twoset=str2[i]+str2[i+1]
        if pattern.findall(twoset):
            str2List.append(twoset)

    # 원소의 중복을 허용하는 다중집합이 아님 교집합이 {1,2,2}가 아닌 {1,2}가 나옴 
    a = set(str1List) & set(str2List)
    b = set(str1List) | set(str2List)

    # 3.1 중복되는 수를 알아낸다. 
    # 따라서 추가되는 수를 알아내고 추가 해줘야함 
    intersection_num = 0
    union_num = 0
    
    # 교집합 
    for i in a:
        if str1List.count(i) > 1 and str2List.count(i) > 1:
            if str1List.count(i) > str2List.count(i):
                intersection_num += str2List.count(i)-1     # -1을 하는 이유는 이미 일반집합에 하나는 넣어져 있어서 
            else:                                           # str1List와 str2List에서 더 적은것을 고른다
                intersection_num += str1List.count(i)-1
    
    # 합집합 
    for i in b:
        if str1List.count(i) > 1 or str2List.count(i) > 1:
            if str1List.count(i) > str2List.count(i):
                union_num += str1List.count(i)-1            # str1List와 str2List에서 더 많은것을 고른다
            else:
                union_num += str2List.count(i)-1            
    
    # 교집합 길이 수에 중복되는 수를 더해주고 합집합도 마찬가지로 해준다
    total_inter = len(a)+intersection_num
    totla_union = len(b)+union_num
    
    # 예외 처리
    if totla_union == 0:
        return 65536

    if total_inter == 0:
        return 0 
    
    # 3. 자카드 유사도를 구한다 
    return int(total_inter / totla_union * 65536)

if __name__ == '__main__':
    
    testcase = [
        ('FRANCE', 'french'),	
        ('handshake', 'shake hands'),
        ('aa1+aa2',	'AAAA12'),
        ('E=M*C^2',	'e=m*c^2')	
    ]

    for str1, str2 in testcase:
        print(solution(str1, str2))
        print()

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.