시간 : 1시간
URL : https://programmers.co.kr/learn/courses/30/lessons/17677
자카드 유사도 계산 방법
J(A, B) : 두 집합의 교집합 크기 / 두 집합의 합집합 크기
A와 B가 공집합인 경우
- J(A, B) = 1
중복을 허용하는 다중 집합에서 사용이 가능
- A ∩ B = 중복 원소의 최솟값
- A ∪ B = 중복 원소의 최댓값
str1
과 str2
의 두 문자열 ( 길이는 2 이상, 1,000 이하 )다중 집합의 원소 리스트를 생성한 후, 문제에서 주어지는 조건대로 자카드 유사도 만 잘 구하면 되는 문제이다. convert() 라는 함수를 통해서 다중 집합의 원소 리스트를 생성하고, calculate() 함수를 이용하여 자카드 유사도를 계산하였다.
def convert(str1, str2):
list1, list2 = [],[]
for i in range(0,len(str1)-1):
list1.append(str1[i:i+2])
for i in range(0,len(str2)-1):
list2.append(str2[i:i+2])
list1 = [i.lower() for i in list1 if i.isalpha()]
list2 = [i.lower() for i in list2 if i.isalpha()]
return list1,list2
def calculate(list1, list2):
# A와 B가 공집합인 경우
if not list1 and not list2:
return 1
# 중복되는 원소가 없는 경우
elif len(list1) == len(set(list1)) and len(list2) == len(set(list2)):
result1 = len(list(set(list1) & set(list2)))
result2 = len(list(set(list1)|set(list2)))
return result1 / result2
# 중복되는 원소가 있는 경우
else:
dict1,dict2 = {},{}
result1 = list(set(list1) & set(list2)) # 곱 원소 (only 1개)
result2 = list(set(list1)|set(list2)) # 합 원소 (only 1개)
len1 = len(result1)
len2 = len(result2)
for i in list1:
if i in dict1:
dict1[i] +=1
else:
dict1[i] = 1
for i in list2:
if i in dict2:
dict2[i] +=1
else:
dict2[i] = 1
for i in result1:
if dict1[i]>1 or dict2[i]>1:
len1 += min(dict1[i],dict2[i])-1
continue
for i in result2:
if (i in list1) and (i not in list2):
len2 += dict1[i]- 1
continue
elif (i in list2) and (i not in list1):
len2 += dict2[i]- 1
continue
elif (i in list2) and (i in list1):
len2 += max(dict1[i], dict2[i])-1
continue
return len1 / len2
def solution(str1, str2):
list1,list2 = convert(str1, str2)
similarity = calculate(list1,list2)
return int(65536 * similarity)
난이도는 쉬운 편이였다. 문제에 주어진 조건만 정리 잘해서 푼다면 쉽게 풀 수 있는 문제였다. 그럼에도 시간이 1시간이나 걸린 이유는 continue와 break를 혼동해서 사용했기 때문이다. 너무나도 사소한 개념 혼동 실수라니 ㅠㅠ 역시 문법 공부도 소홀히 해서는 안되겠다.
i = 0
while True: # 무한 루프
print(i)
i += 1 # i를 1씩 증가시킴
if i == 100: # i가 100일 때
break # 반복문을 끝냄. while의 제어흐름을 벗어남
for i in range(10000): # 0부터 9999까지 반복
print(i)
if i == 100: # i가 100일 때
break # 반복문을 끝냄. for의 제어흐름을 벗어남
for i in range(100): # 0부터 99까지 증가하면서 100번 반복
if i % 2 == 0: # i를 2로 나누었을 때 나머지가 0면 짝수
continue # 아래 코드를 실행하지 않고 건너뜀
print(i)