본문 바로가기
Coding Test/Java

[Java] (프로그래머스 Level 2) 뉴스 클러스터링

by Chaedie 2023. 4. 13.
728x90

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

내 풀이

import java.util.*;

class Solution {
    public int solution(String str1, String str2) {
        // 2글자씩 자르기
        Map<String, Integer> map1 = getSubstringMap(str1.toLowerCase());
        Map<String, Integer> map2 = getSubstringMap(str2.toLowerCase());
        
        // map1, map2의 키값을 각각 순회하면서 map3 map4를 만든다. 이때 map3는 min값으로, map4는 max값으로 만든다.
        Map<String, Integer> minMap = getMinMap(map1, map2);
        Map<String, Integer> maxMap = getMaxMap(map1, map2);
        
        // Math.floor((minMap의 밸류의 합 / maxMap의 밸류의 합 ) * 65536 )
        int minTotal = getTotalValueOfMap(minMap);
        int maxTotal = getTotalValueOfMap(maxMap);
        
        // 공집합 예외처리
        if (minTotal == 0 && maxTotal == 0) return 65536;

        return  (minTotal * 65536) / maxTotal;
    }
    
    private int getTotalValueOfMap(Map<String, Integer> map) {
        int total = 0;
        for (Map.Entry<String, Integer> entry: map.entrySet()) {
            String key = entry.getKey();
            int value = map.get(key);
            total += value;
        }
        return total;
    }
    
    private Map<String, Integer> getMaxMap(Map<String, Integer> map1, Map<String, Integer> map2) {
        Map<String, Integer> map = new HashMap<>();
        for (Map.Entry<String, Integer> entry: map1.entrySet()) {
            String key = entry.getKey();
            int value = Math.max(map1.getOrDefault(key, 0), map2.getOrDefault(key, 0));
            if (value != 0) {
                map.put(key, value);    
            }
        }
        for (Map.Entry<String, Integer> entry: map2.entrySet()) {
            String key = entry.getKey();
            int value = Math.max(map1.getOrDefault(key, 0), map2.getOrDefault(key, 0));
            if (value != 0) {
                map.put(key, value);    
            }
        }
        return map;
    }
    
    private Map<String, Integer> getMinMap(Map<String, Integer> map1, Map<String, Integer> map2) {
        Map<String, Integer> map = new HashMap<>();
        for (Map.Entry<String, Integer> entry: map1.entrySet()) {
            String key = entry.getKey();
            int value = Math.min(map1.getOrDefault(key, 0), map2.getOrDefault(key, 0));
            if (value != 0) {
                map.put(key, value);    
            }
        }
        for (Map.Entry<String, Integer> entry: map2.entrySet()) {
            String key = entry.getKey();
            int value = Math.min(map1.getOrDefault(key, 0), map2.getOrDefault(key, 0));
            if (value != 0) {
                map.put(key, value);    
            }
        }
        return map;
    }
    
    private Map<String, Integer> getSubstringMap(String str){
        Map<String, Integer> map = new HashMap<>();
        char[] chars = str.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length() - 1; i++) {
            if ('a' <= chars[i] && chars[i] <= 'z' && 'a' <= chars[i + 1] && chars[i + 1] <= 'z' ){
                sb.append(chars[i]);
                sb.append(chars[i+1]);
                String key = sb.toString();
                map.put(key, map.getOrDefault(key,0) + 1);
                sb.deleteCharAt(0);
                sb.deleteCharAt(0);    
            }
        }
        
        return map;
    }
}
  • 내 풀이는 맵을 이용해서 단어의 카운트의 min값, max값을 교집합 합집합의 갯수로 계산한 방식이다.
  • 아래 다른 사람 풀이를 검색해보니 ArrayList에 넣고, 포함여부 확인후 교집합List에 넣고, 포함여부와 관계없이 합집합List에 넣는 방식을 택했더라. 코드도 좀 더 간결하고, 시간 복잡도 또한 더욱 좋은 코드로 보인다.

다른 사람 풀이

댓글