Programmers: News Clustering
Conditions
{/* <!– - 자카드 유사도 J(A, B)는 두 집합의 교집합 크기를 합집합 크기로 나눈 값으로 정의.
원소의 중복을 허용하는 다중집합에 대해 확장을 하면, 다중집합의 교집합은 min(A의 해당 원소 개수, B의 해당 원소 개수)를 가지고, 합집합은 max()를 가진다.
각 문자열의 길이는 2 이상 1,000 이하이다.
입력으로 들어온 문자열을 두 글자씩 끊어서 다중집합의 원소로 만든다.
영문자로 된 글자쌍만 유효하고, 공백이나 숫자, 특수 문자가 들어있는 경우 그 글자 쌍을 버린다.
대소문자 차이는 무시한다.
유사도 값은 0에서 1사이 실수이므로 65536을 곱하고 정수부만 출력한다. –> */}
Jaccard similarity
J(A, B)defines the intersection size of the two sets divided by the union size.In multiple set that allows duplication of elements, the intersection has
min(# of elements in A, # of elements in B). And the union hasmax(...).Each string length is 2…1,000.
Cut the input string into two letters and make it as a set.
Only alphabet character pairs are valid and discard the pair if it contains spaces, numbers or special characters.
Differences in upper case and lower case should be ignored.
Since the similarity value is in 0…1 range real number, 65536 should be multiplied and print as integer value.
Strategy
{/* <!– - 파이썬 set 타입은 교집합과 합집합 연산을 제공하지만, 중복이 없는 집합이라 이 방법은 사용 불가.
중복이 허용되는 집합이기 때문에 각 원소의 개수를 세는 작업이 필요.
조건에 나와있는 min, max를 활용한다.
우선 s1의 원소가 s2에 있는 경우는 교집합을 만들 수 있으므로 계산하고, s2에서 그 원소를 제거한다.
s1의 원소가 s2에 없는 경우는 s1에만 있는 경우로 따로 모아둔다.
반복문을 다 돌고 나면 s2에는 s1에 없는 원소만 남아있을 것이고, s1_not_s2에는 s2에 없는 원소만 남아있을 것이다. 이 두 집합에 있는 원소 개수를 모두 합집합에 더한다.
만약 합집합이 0인 경우는 자카드 유사도를 계산할 때 0으로 나눌 수 없으므로 조건에 주어진 대로 1을 곱해서 출력한다.
그렇지 않은 경우, 자카드 유사도를 계산하고 65536을 곱해서 출력한다. –> */}
Python
settype provides intersection and union methods, but these are not available because there is no overlap.Counting the number of each element is required because it is a set that allows overlap.
Use
min()andmax()listed in the conditions.If the element of
s1is ins2, it can be in the intersection set. Calculate it and remove the element froms2.If the element of
s1is not ins2, collect it seperately.After the for statement,
s2has elements which are not ins1.Add the number of elements in the
s1_not_s2ands2to union.If the union is zero, it cannot be divided into zero when calculating the Jaccard similarity, so it should be printed by multiplying 1 as given in the condition.
Otherwise, calculate the similarity and multiply it by 65536, and print only integer part.
1def split2char(str):
2 temp = {}
3 for word in [str[i:i+2] for i in range(len(str)-1)]:
4 if word.isalpha():
5 uppered = word.upper()
6 temp[uppered] = temp.get(uppered, 0) + 1
7 return temp
8
9
10def solution(str1, str2):
11 s1 = split2char(str1);
12 s2 = split2char(str2);
13
14 inter = 0
15 union = 0
16
17 s1_not_s2 = {}
18 for k1, v1 in s1.items():
19 if k1 in s2:
20 inter += min(v1, s2[k1])
21 union += max(v1, s2[k1])
22 del s2[k1]
23 else:
24 s1_not_s2[k1] = v1
25
26 union += sum(list(s1_not_s2.values()))
27 union += sum(list(s2.values()))
28
29 if union == 0:
30 return 65536
31 else:
32 return int(65536 / union * inter)
Remember
{/* <!– - s1_not_s2를 따로 만들지 않고 v1을 바로 union에 더해도 될 것 같다.
중복 허용하는 집합에서 교집합, 합집합을 구하는 방법을 기억해둬야 할 것 같다. –> */}
I think
v1can add directly to the union without makings1_not_s2.I need to remember how to find intersecion and union in this solution.
Comments