
풀이
import java.util.*;
class Solution {
public int solution(String str1, String str2) {
str1 = str1.toUpperCase();
str2 = str2.toUpperCase();
Map<String, Integer> map1 = new HashMap<>();
Map<String, Integer> map2 = new HashMap<>();
makeMap(str1, map1);
makeMap(str2, map2);
Set<String> set = new HashSet<>();
set.addAll(map1.keySet());
set.addAll(map2.keySet());
int intersection = 0;
int union = 0;
for(String s : set) {
int cur1 = map1.getOrDefault(s, 0);
int cur2 = map2.getOrDefault(s, 0);
intersection += Math.min(cur1, cur2);
union += Math.max(cur1, cur2);
}
if(union == 0) {
return 65536;
}
return (int) ((double) intersection / union * 65536);
}
private void makeMap(String str, Map<String, Integer> map) {
for(int i = 0; i < str.length() - 1; i++) {
char cur1 = str.charAt(i);
char cur2 = str.charAt(i + 1);
if(cur1 >= 'A' && cur1 <= 'Z' && cur2 >= 'A' && cur2 <= 'Z') {
String s = str.substring(i, i + 2);
map.put(s, map.getOrDefault(s, 0) + 1);
}
}
}
}
Map<String, Integer> map = new HashMap<>();
문제에서 같은 원소가 여러 번 등장할 수 있으므로 Set이 아니라 Map을 사용한다.
Map에는 Key : 두 글자 문자열 Value : 등장 횟수
map.put(s, map.getOrDefault(s, 0) + 1);
으로 갯수를 증가시킨다.
if (cur1 >= 'A' && cur1 <= 'Z'
&& cur2 >= 'A' && cur2 <= 'Z') {
문제에서는 두 글자가 모두 A~Z인 경우만 인정한다.
Set<String> set = new HashSet<>();
set.addAll(map1.keySet());
set.addAll(map2.keySet());
교집합과 합집합을 계산하려면 두 Map에 존재하는 모든 문자열을 알아야한다.
intersection += Math.min(cur1, cur2);
union += Math.max(cur1, cur2);
교집합 = 등장 횟수의 최소값
합집합 = 등장 횟수의 최대값