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

Hesoyam·2020년 12월 7일
0

내용

   주어진 두 문자열의 자카드 유사도 구현

입력 형식

  🞄 입력으로는 str1과 str2의 두 문자열이 들어온다.

  🞄 각 문자열의 길이는 2 이상, 1,000 이하이다.

  🞄 입력으로 들어온 문자열은 두 글자씩 끊어서 다중집합의 원소로 만든다.
    이때 영문자로 된 글자 쌍만 유효하고, 기타 공백이나 숫자, 특수 문자가 들어있는 경우는
    그 글자 쌍을 버린다. 예를 들어"ab+"가 입력으로 들어오면, "ab"만 다중집합의 원소로 삼고,
    "b+"는 버린다.

  🞄 다중집합 원소 사이를 비교할 때, 대문자와 소문자의 차이는 무시한다.
    "AB"와 "Ab", "ab"는 같은 원소로 취급한다.

출력 형식

입력으로 들어온 두 문자열의 자카드 유사도를 출력한다. 유사도 값은 0에서 1 사이의 실수이므로, 이를 다루기 쉽도록 65536을 곱한 후에 소수점 아래를 버리고 정수부만 출력한다.

예제 입출력

str1 str2 answer
FRANCE french 16384
handshake shake hands 65536
aa1+aa2 AAAA12 43690
E=M*C^2 e=m*c^2 65536

사용 코드

        def solution(str1, str2):
	list_str1 =[]
	list_str2 =[]

	for s1, slice_s1 in zip(str1, str1[1:]) :   # str1 문자만 2글자씩 뽑기
		join_str = "".join([s1,slice_s1])
		if join_str.isalpha() :
			list_str1.append( join_str.lower() )
	
	for s2, slice_s2 in zip(str2, str2[1:]) :    # str2 문자만 2글자씩 뽑기
		join_str = "".join([s2,slice_s2])
		if join_str.isalpha() :
			list_str2.append(join_str.lower())
			

	if len(list_str1) > len(list_str2) : 
	#교집합의 개수를 구함
		inter =  [list_str1.remove(x) for x in list_str2 if x in list_str1] 
	else :
		inter = [list_str2.remove(x) for x in list_str1 if x in list_str2] 

	#합집합은 교집합 + 나머지 원소들 

	list_uni = list_str1 + list_str2
	uni = len(list_uni)
	
	if uni ==0 :
		return 65536
    
	return int(len(inter)/uni * 65536 )

코드 설명

  1. 각 문자열 마다 2글자씩 뽑아서 새로운 리스트에 넣어준다.

  2. 리스트의 길이가 짧은 값을 기준으로 반복문을 돌려 일치한 값이 있으면 remove한 후 해당 값을 inter(교집합) 변수에 받는다.
    ex) a = [1,3,5,7,9] b = [1,2,5]
    b를 기준으로 반복문을 돌렸을때 1,2,5가 a에 존재하면 a와 b 모두 존재하므로 교집합의 원소이다.

  3. 합집합을 구하는 방법은 두 집합 a, b 가 있을때 { a+b - a∩b }이고 2.에서 이미 한쪽에 교집합을 제거했으니 a+b만 하면 합집합이 구해진다.

  4. 입력형식에서 영문자로 된 글자 쌍만 원소로 삼는다는 얘기가 있다. 그 말은 예제 입출력에 마지막처럼 글자 쌍이 영문자로만 이루어지지 않은 경우 원소가 아예 없으니 교집합, 합집합은 0이다.
    그대로 수식에 반영하면 0/0이 되버려서 해당 부분의 예외처리를 하고자 합이 0일 경우 return을 시켰다.
profile
거북이가 되고 싶은 자라

0개의 댓글