코딩 테스트/프로그래머스(LV2)

[프로그래머스] 뉴스 클러스터링(2018 Kakao Blind Recruitment) (LV2 - JavaScript)

dev-hpk 2024. 11. 18. 14:36
 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

1. 문제

제한사항

입출력 예

출력 형식

 

2. 오답

function solution(str1, str2) {
    const arr1 = new Map(); // str1을 두 글자씩 끊어서 만든 다중집합의 원소
    const arr2 = new Map(); // str2를 두 글자씩 끊어서 만든 다중집합의 원소
    let cntUnion = 0; // 합집합 카운트
    let cntIntersection = 0; // 교집합 카운트
    // 비교를 위해 소문자로 통일
    str1 = str1.toLowerCase();
    str2 = str2.toLowerCase();
    
    for (let i=0; i<str1.length-1; i++) {
        // 정규식으로 현재 글자와 다음 글자가 a~z까지 알파벳 소문자인지 확인
        // 조건에 충족하면 arr1(Map)에 value+1
        if (str1[i].match(/[a-z]/) && str1[i+1].match(/[a-z]/)) {
            const t = str1[i] + str1[i+1];
            if (arr1.has(t)) arr1.set(t, arr1.get(t)+1);
            else arr1.set(t, 1);
        }
    }
    
    for (let i=0; i<str2.length-1; i++) {
        // 정규식으로 현재 글자와 다음 글자가 a~z까지 알파벳 소문자인지 확인
        // 조건에 충족하면 arr2(Map)에 value+1
        if (str2[i].match(/[a-z]/) && str2[i+1].match(/[a-z]/)) {
            const t = str2[i] + str2[i+1];
            if (arr2.has(t)) arr2.set(t, arr2.get(t)+1);
            else arr2.set(t, 1);
        }
    }
    
    // 합집합 카운트를 위한 Map 객체 (arr2를 깊은 복사)
    const arrUnion = new Map(JSON.parse(JSON.stringify(Array.from(arr2))));
    
    for (let [key, value] of arr1.entries()) {
    	// arr1과 arr2에 모두 포함된 값인 경우 value를 더 큰 값으로 세팅
        if (arrUnion.get(key)) arrUnion.set(key, Math.max(value, arrUnion.get(key)));
        // arr2에 없는 key 값이면 추가
        else arrUnion.set(key, value);
        // arr1과 arr2에 모두 포함된 값인 경우 둘의 최솟값을 더함
        cntIntersection += Number(Math.min(value, arr2.get(key))) ? Math.min(value, arr2.get(key)) : 0;
    }
    
    // 합집합 수 카운트
    Array.from(arrUnion.values()).forEach(a => cntUnion += a);
    
    if (cntUnion < 1 || cntIntersection < 1) return 65536;
    else return Math.floor(cntIntersection / cntUnion * 65536);
}

 

어디서 틀렸는지 모르겠다... 제한 사항 다시 읽어보면서 해결해야겠다...😂😂

3. 정답 풀이

function solution(str1, str2) {
    const arr1 = new Map(); // str1을 두 글자씩 끊어서 만든 다중집합의 원소
    const arr2 = new Map(); // str2를 두 글자씩 끊어서 만든 다중집합의 원소
    let cntUnion = 0; // 합집합 카운트
    let cntIntersection = 0; // 교집합 카운트
    // 비교를 위해 소문자로 통일
    str1 = str1.toLowerCase();
    str2 = str2.toLowerCase();
    
    for (let i=0; i<str1.length-1; i++) {
        // 정규식으로 현재 글자와 다음 글자가 a~z까지 알파벳 소문자인지 확인
        // 조건에 충족하면 arr1(Map)에 value+1
        if (str1[i].match(/[a-z]/) && str1[i+1].match(/[a-z]/)) {
            const t = str1[i] + str1[i+1];
            if (arr1.has(t)) arr1.set(t, arr1.get(t)+1);
            else arr1.set(t, 1);
        }
    }
    
    for (let i=0; i<str2.length-1; i++) {
        // 정규식으로 현재 글자와 다음 글자가 a~z까지 알파벳 소문자인지 확인
        // 조건에 충족하면 arr2(Map)에 value+1
        if (str2[i].match(/[a-z]/) && str2[i+1].match(/[a-z]/)) {
            const t = str2[i] + str2[i+1];
            if (arr2.has(t)) arr2.set(t, arr2.get(t)+1);
            else arr2.set(t, 1);
        }
    }
    
    // 합집합 카운트를 위한 Map 객체 (arr2를 깊은 복사)
    const arrUnion = new Map(JSON.parse(JSON.stringify(Array.from(arr2))));
    
    for (let [key, value] of arr1.entries()) {
    	// arr1과 arr2에 모두 포함된 값인 경우 value를 더 큰 값으로 세팅
        if (arrUnion.get(key)) arrUnion.set(key, Math.max(value, arrUnion.get(key)));
        // arr2에 없는 key 값이면 추가
        else arrUnion.set(key, value);
        // arr1과 arr2에 모두 포함된 값인 경우 둘의 최솟값을 더함
        cntIntersection += Number(Math.min(value, arr2.get(key))) ? Math.min(value, arr2.get(key)) : 0;
    }
    
    // 합집합 수 카운트
    Array.from(arrUnion.values()).forEach(a => cntUnion += a);
    
    if (cntUnion < 1) return 65536;
    else return Math.floor(cntIntersection / cntUnion * 65536);
}

 

집합 A와 집합 B가 모두 공집합일 경우에는 나눗셈이 정의되지 않으니 따로 J(A, B) = 1로 정의한다.

위 제한 사항 문구를 보고 아래처럼 조건식으로 교집합 or 합집합이 0인 경우 1을 리턴(65536을 출력에 곱해야 하기 때문에 1은 생략)해서 통과를 못했다. 

if (cntUnion < 1 || cntIntersection < 1) return 65536;

 

합집합이 0인 경우는 나눗셈이 성립 안되기 때문에 1을 리턴하는 게 맞지만, 교집합이 없는 경우는 0을 리턴해야 한다.

조금만 생각하고 조건문 작성했으면 고생할 일도 없었을 텐데... 그래도 덕분에 코드 다시 정독해 보고 좋은 기회였다고 생각하자😅😅😅

 

 

[프로그래머스] 전화번호 목록 (LV2 - JavaScript)

프로그래머스SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프programmers.co.kr1. 문제 제한사항 입출력 예입출력 예 설명2. 오답function solution(phone_book) {

dev-hpk.tistory.com

 

 

[프로그래머스] 프로세스 (LV2 - JavaScript)

프로그래머스SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프programmers.co.kr1. 문제제한사항 입출력 예입출력 예 설명 2. 정답 풀이풀이 전략큐 활용.

dev-hpk.tistory.com