💡Problem Solving/Programmers
[프로그래머스] 뉴스 클러스터링 (Java)
gom20
2021. 10. 23. 13:05
#문제
https://programmers.co.kr/learn/courses/30/lessons/17677
코딩테스트 연습 - [1차] 뉴스 클러스터링
뉴스 클러스터링 여러 언론사에서 쏟아지는 뉴스, 특히 속보성 뉴스를 보면 비슷비슷한 제목의 기사가 많아 정작 필요한 기사를 찾기가 어렵다. Daum 뉴스의 개발 업무를 맡게 된 신입사원 튜브
programmers.co.kr
#풀이
1. 각 문자열을 두 문자씩 쪼개서 Map<String, Integer>에 넣는다. 이때 value값은 해당 문자가 나온 횟수이다.
- 정규식을 이용해 특수문자가 포함된 문자를 필터링한다.
- 이 때 원소의 총 개수를 count한다.
2. 교집합의 개수를 구한다.
- 둘 중 하나의 맵을 순회하면서 다른 맵의 동일한 key가 있는지 체크하여, 동일한 key가 있으면 value의 Min값의 합을 구한다.
3. 합집합의 원소를 구한다.
- 전체 원소 개수 - 교집합 원소 개수
- 합집합이 공집합일 경우 65536 리턴한다.
- 이 외 케이스는 자카드 유사도 계산하여 리턴한다.
Java 정규식에서 영문자 이외에 모든 문자를 제거하고 싶을 때는 [^A-Za-z] 괄호 안에 ^ 기호를 붙여서 사용한다.
괄호 밖에 있으면 첫번째 등장하는 조건이니 유의해야한다.
#소스코드
import java.util.*;
import java.util.regex.*;
class Solution {
public HashMap<String, Integer> map1, map2;
public int solution(String str1, String str2) {
int answer = 0;
map1 = new HashMap<String, Integer>();
map2 = new HashMap<String, Integer>();
str1 = str1.toUpperCase();
str2 = str2.toUpperCase();
Pattern p = Pattern.compile("[^A-Za-z]");
Matcher m = null;
int totalCnt = 0;
for(int i = 0; i <= str1.length()-2; i++){
String key = str1.substring(i, i+2);
m = p.matcher(key);
if(m.find()) continue;
map1.put(key, map1.getOrDefault(key, 0) + 1);
totalCnt++;
}
for(int i = 0; i <= str2.length()-2; i++){
String key = str2.substring(i, i+2);
m = p.matcher(key);
if(m.find()) continue;
map2.put(key, map2.getOrDefault(key, 0) + 1);
totalCnt++;
}
int interCnt = 0;
for(String key : map1.keySet()){
if(map2.get(key) == null) continue;
interCnt += Math.min(map2.get(key), map1.get(key));
}
int unionCnt = totalCnt - interCnt;
if(unionCnt == 0) return 65536;
return interCnt*65536/unionCnt;
}
}