[1차] 뉴스 클러스터링
문제링크
풀이
- 입력으로 들어온 문자열은 두 글자씩 끊어서 다중집합의 원소로 만든다. 단, 만들 때 해당 문자열이 알파벳으로 이루어져 있는지 확인 후 만든다.
- str1, str2 에 대해 다중 집합을 모두 만든 후, 두 집합이 공집할 일 경우에는 바로 자카드 유사도 값 1을 활용해 계산된 결과값 65535을 리턴한다.
- 두 집합이 모두 공집합인 경우가 아닐 경우, 각각 교집합과 차집합에 대하여 계산한다.
합집합(unionSet)의 경우, 두 집합을 합하여 넣은 후, 교집합(intersection) 부분에 대하여 set1, set2의 max값을 계산한다.
교집합의 경우의 set1, set2에 모두 포함하고 원소에 대하여 min값을 계산하여 구한다.
- 자카드 유사도 값을 계산 후, 65536을 곱하여 리턴한다.
코드
import java.util.*;
class Solution {
public int solution(String str1, String str2) {
str1 = str1.toUpperCase();
str2 = str2.toUpperCase();
Map<String, Integer> set1 = new HashMap<>();
Map<String, Integer> set2 = new HashMap<>();
int intersection = 0;
int union = 0;
for (int i = 0; i < str1.length() -1; i++){
String subStr = str1.substring(i, i+ 2);
if (subStr.matches("^[a-zA-Z]*$")) {
set1.put(subStr, set1.getOrDefault(subStr, 0) + 1);
}
}
for (int i = 0; i < str2.length() -1; i++){
String subStr = str2.substring(i, i+ 2);
if (subStr.matches("^[a-zA-Z]*$")) {
set2.put(subStr, set2.getOrDefault(subStr, 0) + 1);
}
}
if (set1.isEmpty() && set2.isEmpty()) {
return 65536;
}
Map<String, Integer> unionSet = new HashMap<>();
unionSet.putAll(set1);
unionSet.putAll(set2);
for(Map.Entry<String, Integer> e1 : set1.entrySet()){
if (set2.containsKey(e1.getKey())) {
intersection += Math.min(e1.getValue(), set2.get(e1.getKey()));
unionSet.put(e1.getKey(), Math.max(e1.getValue(), set2.get(e1.getKey())));
}
}
for (Integer value : unionSet.values()) {
union += value;
}
return (int) (intersection * 65536 / union);
}
}