1. 나의 첫 풀이
- 두 집합 A, B 구하기
1.1 문자열을 소문자로 바꾼다 (lower())
2.2 두글자씩 끊긴 문자열의 개수를 계산한다. 이때 알파벳만 인정 (isalpha())
- 자카드 유사도 구하기
2.1 교집합 원소 개수 구하기
2.2 합집합 원소 개수 구하기
2.3 유사도 반환
3 65536을 곱하고 소수부분 버리기 (int())
def J_sim(A, B):
if len(A) == 0 and len(B) == 0:
return 1
intersect, union = {}, {}
for a in A.keys():
if B.get(a, 0) > 0:
intersect[a] = min(A[a], B[a])
union[a] = max(A.get(a, 0), B.get(a, 0))
for b in B.keys():
union[b] = max(A.get(b, 0), B.get(b, 0))
n_intersect, n_union = 0, 0
for k in intersect.keys():
n_intersect += intersect[k]
for k in union.keys():
n_union += union[k]
return n_intersect / n_union
def solution(str1, str2):
answer = 0
A, B = {}, {}
str1 = str1.lower()
str2 = str2.lower()
for i in range(len(str1)-1):
sub_str = str1[i:i+2]
if sub_str.isalpha():
A[sub_str] = A.get(sub_str, 0) + 1
for i in range(len(str2)-1):
sub_str = str2[i:i+2]
if sub_str.isalpha():
B[sub_str] = B.get(sub_str, 0) + 1
answer = int(65536 * J_sim(A, B))
return answer
2. 다른사람의 풀이
- 정규표현식으로 문자열 거르기
re.findall('[^a-zA-Z]+')
1.1 알파벳만 거르면 되는데 정규표현식은 too much라고 생각한다.
1.2 실제 코테에서도 import re가 가능한지 의문
- 교집합, 합집합 연산을 set의 &, | 연산으로 해결
2.1 집합에서 합집합, 교집합 연산은 O(n)이므로 코드가 간결하다
2.2 union(), intersection()을 활용해볼까?
- A, B집합은 처음엔 리스트로, 나중에 집합처럼 구한다
3.1 굳이 딕셔너리로 하지 않고도 가능한 풀이
Counter를 활용하여 개수 세기
4.1 실제 코딩에서 자주 사용되는 Counter를 코테에서 활용하기
4.2 실제 코테에서도 컬렉션을 사용할 수 있는가?