본문 바로가기
[ 다먹살 ]/- Coding

[프로그래머스] 레벨2 뉴스 클러스터링

by 엉망으로살기 2021. 8. 27.
반응형

https://programmers.co.kr/learn/courses/30/lessons/17677?language=java 

 

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

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

programmers.co.kr

 

이 문제는 일단 문제 길이가 너무나 길었다. 그래서 사실 다른 걸 풀어보려고 했는데 자세히 보니 앞에는 다 서론이어서 문제랑 관련이 없는 부분이었고, 실제로 문제 설명은 길이도 짧고 생각보다 어렵지도 않았다.

 

1.파라미터로 받은 문자열 2개에 대해 각각 다중집합을 구해서 map 자료구조로 넣는다.

  1-1. 대소문자 구분이 없으므로, 모두 대문자로 변경한다.

  1-2. 현재, 다음 인덱스의 문자가 영어 대문자인 경우 집합 중 1개로 인식하고 map에 넣는다.

  1-3. 중복이 허용되므로 이미 map에 있는 집합일 경우에는 현재 개수 +1 한다.

2. map에 저장된 집합을 확인하며 교집합의 크기를 구해준다.

  2-1. 이 때 교집합이므로, 양쪽 map 중 더 작은 개수를 교집합 값으로 가져온다.

3. 양쪽 map의 크기를 통해 합집합의 크기를 구해준다.

  3-1. 만약 양쪽 map의 크기가 모두 0이라면 자카드 유사도를 1로 취급하고, 65536을 리턴한다.

4. 정수 형태로 리턴해야하므로 강제 자료형 캐스팅을 한 후에 리턴한다.

 


문제

입출력 형식 및 예제


코드

import java.util.HashMap;

class Solution
{
    public int solution(String str1, String str2)
    {
        // 입력값 대소문자 구분 x
        str1 = str1.toUpperCase();
        str2 = str2.toUpperCase();
        
        // 다중집합과 다중집합의 갯수를 저장할 자료구조
        HashMap<String, Integer> map1 = new HashMap<String, Integer>();
        HashMap<String, Integer> map2 = new HashMap<String, Integer>();


        // 교집합, 합집합 크기 변수 및 임시 문자열 변수
        int gyo = 0;
        int size1 = 0;
        int size2 = 0;
        String input = "";
            
        // str1에 대한 다중집합 및 갯수 처리
        for(int i=0; i<str1.length()-1; i++)
        {
            // 영어 대문자일 경우에만 로직처리
            if(str1.charAt(i)>='A' && str1.charAt(i)<='Z' && str1.charAt(i+1)>='A' && str1.charAt(i+1)<='Z')
            {
                input = str1.charAt(i) + "" + str1.charAt(i+1);
                
                // 이미 map에 있는 문자열일 경우에는 기존갯수 +1 
                if(map1.containsKey(input))
                {
                    map1.put(input, map1.get(input)+1);
                }
                else
                {
                    map1.put(input, 1);
                }
            }
        }
        
        // str2도 str1과 동일한 방법으로 처리
        for(int i=0; i<str2.length()-1; i++)
        {
            if(str2.charAt(i)>='A' && str2.charAt(i)<='Z' && str2.charAt(i+1)>='A' && str2.charAt(i+1)<='Z')
            {
                input = str2.charAt(i) + "" + str2.charAt(i+1);
                
                if(map2.containsKey(input))
                {
                    map2.put(input, map2.get(input)+1);
                }
                else
                {
                    map2.put(input, 1);
                }
            }
        }
        
        // 2개의 map에 모두 다중집합이 존재할 경우, 작은 갯수를 교집합 크기로 +
        for(String data : map1.keySet())
        {
            if(map2.containsKey(data))
            {
                gyo += Math.min(map1.get(data), map2.get(data));
            }
        }
        
        // 예외처리 : 파라미터 2개에 대한 유효 다중집합이 없을경우, 자카드 유사도를 1로 처리하고 65536 리턴
        if(map1.size()==0 && map2.size()==0)
        {
            return 65536;
        }
        
        // 합집합 크기를 구하기 위해 map들에 대한 사이즈 구하기
        for(Integer d1 : map1.values())
        {
            size1 += d1;
        }
        
        for(Integer d2 : map2.values())
        {
            size2 += d2;
        }
        
        // 결과를 정수 형태로 리턴
        return (int)((gyo*65536)/(size1+size2-gyo));
    }
}

 

반응형

댓글