'자카드 유사도'는 집합 간의 유사도를 검사하는 여러 방법 중의 하나로 알려져 있다. 두 집합 A
,B
사이의 자카드 유사도 J(A,B)
는 두 집합의 교집합 크기를 두 집합의 합집합 크기로 나눈 값으로 정의한다.
집합 A와 집합 B가 모두 공집합일 경우에는 나눗셈이 정의되지 않으니 따로 J(A,B)
= 1로 정의한다.
이를 이용하여 문자열 사이의 유사도를 계산하는데 이용할 수 있다.
str1
과 str2
의 두 문자열이 들어온다. 각 문자열의 길이는 2 이상 1,000 이하이다.입력으로 들어온 두 문자열의 자카드 유사도를 출력한다. 유사도 값은 0에서 1 사이의 실수이므로, 이를 다루기 쉽도록 65536을 곱한 후에 소수점 아래를 버리고 정수부만 출력한다.
maps = { 원소: [str1에서의 개수, str2에서의 개수] }
def solution(str1, str2):
maps = {} # 집합A, 집합B
makeSet(maps, str1, 0)
makeSet(maps, str2, 1)
union, inter = 0, 0 # 합집합의 개수, 교집합의 개수
for item in maps.values():
inter += min(item)
union += max(item)
if union == 0: return 65536
return int((inter/union) * 65536)
def makeSet(sets, strs, index):
for s in range(len(strs)-1):
if check(strs[s]) and check(strs[s+1]):
tmp = (strs[s] + strs[s+1]).lower()
if tmp in sets:
sets[tmp][index] += 1
else:
sets[tmp] = [0,0]
sets[tmp][index] = 1
def check(c):
return 'a'<=c<='z' or 'A'<=c<='Z'