만족은 하되 안주하지는 말자

기록해야 기억한다

프로그래밍/programmers&bj

[JAVA] 뉴스 클러스터링

D36choi 2022. 3. 18. 15:25
728x90

문제

https://programmers.co.kr/learn/courses/30/lessons/17677

 

코딩테스트 연습 - [1차] 뉴스 클러스터링

뉴스 클러스터링 여러 언론사에서 쏟아지는 뉴스, 특히 속보성 뉴스를 보면 비슷비슷한 제목의 기사가 많아 정작 필요한 기사를 찾기가 어렵다. Daum 뉴스의 개발 업무를 맡게 된 신입사원 튜브

programmers.co.kr

내 풀이

import java.util.*;
import java.util.Map.Entry;

class Solution {

  public int solution(String str1, String str2) {
    int answer = 0;
    str1 = str1.toLowerCase();
    str2 = str2.toLowerCase();

    // 교 - 민
    double intersectionCount = intersection(str1, str2);
    // 합 - 맥
    double unionCount = union(str1, str2);

    double similar = 0;
    if(intersectionCount == 0 && unionCount == 0) {
        similar = 1;
    } else {
        similar = intersectionCount / unionCount; 
    }

    return (int) Math.floor(similar * 65536);
  }

  private double intersection(String str1, String str2) {
    Map<String, Integer> records = getRecords(str1);

    double count = 0;

    for (int i=0; i<str2.length()-1; i++) {
      char c1 = str2.charAt(i);
      char c2 = str2.charAt(i+1);
      if (isAlphabet(c1, c2)) {
        String key = str2.substring(i, i+2);
        if (records.containsKey(key)) {
          if (records.get(key) == 1) {
            records.remove(key);
          } else {
            records.put(key, records.get(key) - 1);
          }
          count++;
        }
      }
    }
    return count;
  }

  private double union(String str1, String str2) {
    Map<String,Integer> records1 = getRecords(str1);
    Map<String,Integer> records2 = getRecords(str2);
    double count = 0;
    for (Entry<String, Integer> entry : records1.entrySet()) {
      if (records2.containsKey(entry.getKey())) {
        count += Math.max(entry.getValue(), records2.get(entry.getKey()));
        records2.remove(entry.getKey());
      } else {
        count += entry.getValue();
      }
    }
    for (Entry<String, Integer> entry : records2.entrySet()) {
      count += entry.getValue();
    }
    return count;
  }

  private Map<String,Integer> getRecords(String str1) {
    Map<String, Integer> records = new HashMap<>();

    for(int i=0; i<str1.length()-1; i++) {
      char c1 = str1.charAt(i);
      char c2 = str1.charAt(i+1);
      if (isAlphabet(c1, c2)) {
        String key = str1.substring(i, i+2);
        records.put(key, records.getOrDefault(key, 0) + 1);
      }
    }
    return records;
  }

  private boolean isAlphabet(char c1, char c2) {
    return ('a' <= c1 && c1 <= 'z') && ('a' <= c2 && c2 <= 'z');
  }
}

알게 된 것

- 다른 사람들을 보면은 정규표현식을 활용하거나 하는데, 위처럼 character 의 값을 비교하면은 쉽게 알파벳을 거를 수 있다.

- 합집합과 교집합은 Map 의 비교를 통해 갯수를 구하거나 할 수 있다

- 중복이 허용된다면 카운터를 이용해야 한다

 

피드백

java stream 기능을 활용하면 보다 가독성 좋게 합집합, 교집합, 집합을 구해낼 수 있다.

 

private Map<String, Long> group(String word) {
        return IntStream.range(0, word.length() - 1)
                .mapToObj(index -> word.substring(index, index + 2))
                .filter(text -> text.chars().allMatch(character -> Character.isAlphabetic((char) character)))
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    }

    private Integer getIntersection(Map<String, Long> words1, Map<String, Long> words2) {
        return words1.entrySet().stream()
                .filter(entry -> words2.containsKey(entry.getKey()))
                .map(entry -> Math.min(entry.getValue(), words2.get(entry.getKey())))
                .mapToInt(Long::intValue)
                .sum();
    }

    private Integer getUnion(Map<String, Long> words1, Map<String, Long> words2) {
        Map<String, Long> copiedWords = new HashMap<>(words2);
        words1.forEach((key, value) -> copiedWords.put(key, Math.max(value, words2.getOrDefault(key, 0L))));

        return copiedWords.values().stream()
                .mapToInt(Long::intValue)
                .sum();

    }

 

'프로그래밍 > programmers&bj' 카테고리의 다른 글

[JAVA] 다단계 칫솔 판매  (0) 2022.03.28
[python] k진수에서 소수 개수 구하기  (0) 2022.03.22
[python] 메뉴 리뉴얼  (0) 2022.03.13
[JAVA] 카카오프렌즈 컬러링북  (0) 2022.03.06
[JAVA] 문자열 압축  (0) 2022.02.21