연습장/프로그래머스 문제풀이

[프로그래머스 Level 2] 뉴스 클러스터링 - JavaScript

Tesseractjh 2022. 5. 16. 12:10

🔗 문제 링크

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

 

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

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

programmers.co.kr

✏️ 풀이

function solution(str1, str2) {
    const getCount = (str) => {
        return [...str]
        .slice(0, -1)
        .map((v, i) => (v + str[i + 1]).toLowerCase())
        .filter(v => !v.match(/[^a-z]/g))
        .reduce((acc, v) => {
            if (acc[v]) {
                acc[v]++;
            } else {
                acc[v] = 1;
            }
            return acc;
        }, {});
    };

    const A = getCount(str1);
    const B = getCount(str2);
    
    const keys = new Set([...Object.keys(A), ...Object.keys(B)]);
    let intersection = 0;
    let union = 0;

    for (const key of keys) {
        if (A[key] && B[key]) {
            intersection += Math.min(A[key], B[key]);
            union += Math.max(A[key], B[key]);
        } else if (A[key]) {
            union += A[key];
        } else if (B[key]) {
            union += B[key];
        }
    }

    return !intersection && !union
        ? 65536
        : Math.floor((intersection / union) * 65536);
}

getCount 함수로 각각의 문자열에 대해 다중집합의 원소와 그 개수를 구한다.

 

그 다음, A와 B의 모든 종류의 원소를 순회한다.

A와 B에 모두 속한 원소는 교집합과 합집합 모두에 속해야 한다. 교집합에는 A와 B중 해당 원소의 개수가 더 적은 쪽의 원소의 개수만큼 포함되고, 합집합에는 A와 B중 해당 원소의 개수가 더 많은 쪽의 원소의 개수만큼 포함된다.

그 외에 A 또는 B 한 쪽에만 속하는 원소는 합집합에만 속해야 한다. 해당 원소의 개수 그대로 합집합에 포함된다.

 

마지막으로 교집합과 합집합이 모두 0인 경우는 유사도를 1로 처리하고, 유사도에 65536을 곱하여 나온 수의 정수부를 출력하였다.