sm 기술 블로그

[1차] 뉴스 클러스터링 (2018 KAKAO BLIND RECRUITMENT) - 파이썬 본문

문제/프로그래머스_파이썬

[1차] 뉴스 클러스터링 (2018 KAKAO BLIND RECRUITMENT) - 파이썬

sm_hope 2022. 10. 17. 20:17
import re

def solution(str1, str2):
    str1 = str1.lower()
    str2 = str2.lower()
    str1 = re.sub(r'[^a-z]', ".", str1)
    str2 = re.sub(r'[^a-z]', ".", str2)

    if(str1 == str2):
      return 65536

    arr1 = dict()
    arr2 = dict()

    up = 0
    down = 0

    for i in range(0, len(str1)-1):
      tmp = str1[i] + str1[i+1]
      if(tmp.find(".") == -1):
        try:
          arr1[tmp] += 1
        except:
          arr1[tmp] = 1
    
    for i in range(0, len(str2)-1):
      tmp = str2[i] + str2[i+1]
      if(tmp.find(".") == -1):
        try:
          arr2[tmp] += 1
        except:
          arr2[tmp] = 1
    
    for val1 in arr1:
      try:
        arr2[val1]
        if(arr2[val1] < arr1[val1]):
          up += arr2[val1]
          down += arr1[val1]
        else:
          up += arr1[val1]
          down += arr2[val1]
      except:
          down += arr1[val1]
      
    for val2 in arr2:
      try:
        arr1[val2]
      except:
          down += arr2[val2]
  
    return (int((up/down) * 65536))

문제요약

문자열을 두개씩 잘라서 문자열인 경우에만 집합으로 처리한다.

두 문자열의 교집합 / 합집합을 구하라.

설명

    str1 = str1.lower()
    str2 = str2.lower()
    str1 = re.sub(r'[^a-z]', ".", str1)
    str2 = re.sub(r'[^a-z]', ".", str2)

문자열을 소문자로 바꾸고, 정규화를 통해 문자가 아닌 것들은 .으로 바꿔준다.

 

    if(str1 == str2):
      return 65536

    arr1 = dict()
    arr2 = dict()

    up = 0
    down = 0

두 문자가 같으면 굳이 계산과정이 필요 없으므로 65536으로 리턴해준다.

 

두개의 딕셔너리를 사용할 것이다.

up은 교집합, down은 합집합이다.

    for i in range(0, len(str1)-1):
      tmp = str1[i] + str1[i+1]
      if(tmp.find(".") == -1):
        try:
          arr1[tmp] += 1
        except:
          arr1[tmp] = 1
    
    for i in range(0, len(str2)-1):
      tmp = str2[i] + str2[i+1]
      if(tmp.find(".") == -1):
        try:
          arr2[tmp] += 1
        except:
          arr2[tmp] = 1

.이 포함되어 있다면 규칙에 어긋나므로 버려주고, 그게 아니라면 딕셔너리에 저장해준다.

 

    for val1 in arr1:
      try:
        arr2[val1]
        if(arr2[val1] < arr1[val1]):
          up += arr2[val1]
          down += arr1[val1]
        else:
          up += arr1[val1]
          down += arr2[val1]
      except:
          down += arr1[val1]
      
    for val2 in arr2:
      try:
        arr1[val2]
      except:
          down += arr2[val2]

첫번째 구문은 A기준으로 B와 교집합, 합집합을 구한다.

두번째 구문은 B기준으로 A와 합집합을 구한다.

 

다시말해

 

첫번째 구문은

다음과 같고

 

두번째 구문은

다음과 같다.

 

즉, 첫번째 구문에서는 교집합과 A에서 교집합을 제외한 부분을, 두번째 구문에서는 B에서 교집합을 제외한 부분이다.

 

   return (int((up/down) * 65536))

최종적으로 소수점을 제거하기 위해 다음과 같이 표현하였다.

Comments