본문 바로가기
알고리즘/PROGRAMMERS

뉴스 클러스터링(Lv.2)

by 현대타운301 2024. 3. 24.

 


 

문제 설명

 

 

 

입출력 예시

 

 

요약

각 문자열에 대해 크기가 2인 문자열의 집합을 구한 후 서로 비교

 


 

풀이

 

접근 방식

1. 문자열로 집합 만들기

  → makeSet() 메소드를 통해 집합 리스트 생성

  → Character.isAlphabetic()으로 알파벳만 포함

 

2. 교집합 구하기

  → .equalsIgnoreCase()를 통해 대소문자 구분 없이 비교 (완전 탐색)

 

3. 합집합 구하기

  → 두 개의 집합 리스트를 더한 union에서 교집합 원소들 제거

  → stream().anyMatch()를 통해 비교 후 제거

 


 

코드리뷰

 

import java.util.*;

class Solution {
    List<String> list1 = new ArrayList<>();
    List<String> list2 = new ArrayList<>();
    List<String> inter = new ArrayList<>();
    List<String> union = new ArrayList<>();
    
    public List<String> makeSet(String str) {   // 집합 생성 메소드
        List<String> list = new ArrayList<>();
        while(str.length() > 1) {	// 남아 있는 문자열의 크기가 1보다 크면 실행
             // 첫 번째 문자와 두 번째 문자 모두 알파벳인 경우
            if(Character.isAlphabetic(str.charAt(0)) && Character.isAlphabetic(str.charAt(1))) {
                list.add(str.substring(0, 2));	// 집합 list에 추가
                union.add(str.substring(0, 2));	// 합집합 list에 추가
                str = str.substring(1);	// 문자열에서 첫 번째 문자 제거
            } else {
                str = str.substring(1);	// 둘 중 하나라도 알파벳이 아닌 경우 문자열에서 첫 번째 문자 제거
            }
        }
        return list;
    }
    
    public int solution(String str1, String str2) {
        // 1. 집합 list 만들기
        list1 = makeSet(str1);
        list2 = makeSet(str2);
        // 2. 교집합 구하기
        for(int i = 0; i < list1.size(); i++) {	// 완전 탐색
            for(int j = 0; j < list2.size(); j++) {
                if(list1.get(i).equalsIgnoreCase(list2.get(j))) {	// 대소문자 구분 없이 같은지 비교
                    inter.add(list1.get(i));	// 같다면 교집합 list에 추가
                    list2.remove(j);	// 비교 대상인 list2에서 해당 요소 제거
                    break;	// 같은 문자가 뒤에 존재할 수 있기 때문에 중복 저장을 피하기 위해 break로 탈출
                }
            }
        }
        // 3. 합집합 구하기
        for(String target : inter) {
            if(union.stream().anyMatch(others -> others.equalsIgnoreCase(target))) {
                union.remove(union.indexOf(target));	// union에서 교집합 원소 제거
            }
        }
        int answer = 0;
        // 두 집합이 모두 공집합인 경우 자카드 유사도는 1
        if(list1.size() == 0 && list2.size() == 0) {
            answer = 65536;
        } else {
            // (교집합 크기) / (합집합 크기) 연산을 통해 자카드 유사도 구하기
            answer = (int)((double)inter.size() / union.size() * 65536);
        }
        return answer;	// 정수(int)로 형변환 후 return
    }
}