[Java] 프로그래머스 LV.2 [1차] 뉴스 클러스터링

영우·2026년 7월 19일

풀이

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);

교집합 = 등장 횟수의 최소값
합집합 = 등장 횟수의 최대값

0개의 댓글