[Lv2, 62%, JS] 뉴스 클러스터링

오늘처음해요·2024년 1월 22일
0

문제

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

2018 KAKAO BLIND RECRUITMENT - [1차] 뉴스 클러스터링

문자열의 유사도를 비교해서 출력하는 문제

내 답

function solution(str1, str2) {
  	const TIMES_NUMBER = 65536
    const str1Arr = [];
    const str2Arr = [];
    const str1Obj = {};
    const str2Obj = {};
    let result;
        
    const regex = /^[a-zA-Z]+$/;
    
    const splitStr = (str,arr) => {
        const deque = [];
        [...str.toUpperCase()].forEach(el => {
        if(!regex.test(el)) return deque.pop();
        if(!deque.length) return deque.push(el);
        deque.push(el);
        arr.push(deque.join(''))
        deque.shift();
        })
    }
    
    const makeObj = (arr,obj) => {
        arr.forEach(el => {
            if(!obj[el]) obj[el] = 0
            obj[el] += 1;
        })
    }
    
    const countIntersection = (obj1, obj2) => {
        const intersection = {};
        for(str in obj1){
            if(obj2[str]) intersection[str] = Math.min(obj1[str],obj2[str])
        }
        return Object.entries(intersection).reduce((acc,cur) => acc += cur[1],0)
    }

    const countUnion = (obj1, obj2) => {
        const union = {};
        for(str in obj1){
            union[str] = obj1[str];
        }
        
        for(str in obj2){
            union[str] = obj2[str]
            if(obj1[str]) union[str] = Math.max(obj1[str],obj2[str]);
        }
       return Object.entries(union).reduce((acc,cur) => acc += cur[1],0)
    }
    
    splitStr(str1, str1Arr);
    splitStr(str2, str2Arr);
    if(!str1Arr.length && !str2Arr.length) return TIMES_NUMBER
    
    makeObj(str1Arr, str1Obj);
    makeObj(str2Arr, str2Obj);
    
    result = Math.floor(countIntersection(str1Obj, str2Obj) / countUnion(str1Obj, str2Obj) * TIMES_NUMBER)
    
    return result
}

내 고민


오히려 고민은 적었던 것 같다

해야하는 게 명확해서 그것을 하나씩 구현하면 됐던 문제

문제는 시간이 너무 오래걸렸다는 것인데

이거 푸는데 한 시간이나 걸려버렸다


내 답 풀이

    const regex = /^[a-zA-Z]+$/;
    
    const splitStr = (str,arr) => {
        const deque = [];
        [...str.toUpperCase()].forEach(el => {
        if(!regex.test(el)) return deque.pop();
        if(!deque.length) return deque.push(el);
        deque.push(el);
        arr.push(deque.join(''))
        deque.shift();
        })
    }

입력받은 str을 요소를 정규식으로 문자인지 확인 후에 deque에 넣고
문자를 두 글자씩 배열에 넣어주는 함수

    const makeObj = (arr,obj) => {
        arr.forEach(el => {
            if(!obj[el]) obj[el] = 0
            obj[el] += 1;
        })
    }

배열의 요소를 객체에 { str : 배열 내의 str 개수 }의 형태로 저장


    const countIntersection = (obj1, obj2) => {
        const intersection = {};
        for(str in obj1){
            if(obj2[str]) intersection[str] = Math.min(obj1[str],obj2[str])
        }
        return Object.entries(intersection).reduce((acc,cur) => acc += cur[1],0)
    }

입력받은 객체들의 교집합 수를 리턴

    const countUnion = (obj1, obj2) => {
        const union = {};
        for(str in obj1){
            union[str] = obj1[str];
        }
        
        for(str in obj2){
            union[str] = obj2[str]
            if(obj1[str]) union[str] = Math.max(obj1[str],obj2[str]);
        }
       return Object.entries(union).reduce((acc,cur) => acc += cur[1],0)
    }

입력받은 객체들의 합집합 수를 리턴


 	splitStr(str1, str1Arr);
    splitStr(str2, str2Arr);
    if(!str1Arr.length && !str2Arr.length) return TIMES_NUMBER
    
    makeObj(str1Arr, str1Obj);
    makeObj(str2Arr, str2Obj);
    
    result = Math.floor(countIntersection(str1Obj, str2Obj) / countUnion(str1Obj, str2Obj) * TIMES_NUMBER)
    
    return result

위의 함수들을 사용해서 정답을 리턴해줬다

0개의 댓글