뉴스 클러스터링

Happhee·2022년 2월 5일
0

[ Lv2 ] programmers

목록 보기
15/32
post-thumbnail

📝 뉴스 클러스터링

🖥 나의 JS 코드

첫번째 시도

반복문 구조가 이상하여 한참을 쳐다본 코드이다.
합집합과 교집합을 구하기 위해서 count1, count2값을 조정하는데, 이에 대한 반복문을 실행할 때,

if (str[j] === union[i])
  count1++;
else
  break;	// 테스트 통과를 못한 부분

else문으로 break를 걸어서 정확한 개수를 파악하지 못한 것이 문제점이었다.
따라서 반복되는 단어의 정확한 갯수를 파악하여 문제를 해결하도록 break를 삭제하였다

최종 코드는 다음과 같다👇

// 단어들의 집합을 구해내기 위한 함수
function getStringSet(str){
    let set = [];
    const alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    for(let i = 0 ; i < str.length-1 ; i++){
        if(alpha.includes(str[i]) && alpha.includes(str[i+1]))
            set.push(str[i] + str[i+1])
    }
    return set;
}

function solution(str1, str2) {
  // str1, str2을 모두 대문자로 바꾼 뒤
  // 이에 대한 단어들의 집합으로 변경
     str1 = getStringSet(str1.toUpperCase());
     str2= getStringSet(str2.toUpperCase());
   
  // 중복되는 단어는 삭제하여 set에 저장
    let str1_set = str1.filter((data,index)=> str1.indexOf(data) === index);
    let str2_set = str2.filter((data,index)=> str2.indexOf(data) === index);
  
  // 교집합
    let intersection = str1_set.filter((data)=> str2_set.includes(data))
    
 // 합집합
    let union = [...new Set(str1) ,...new Set(str2)]
    union = [...new Set(union)]
    
  // 교집합 원소의 수, 합집합 원소의 수 초기화
    let inter_count = 0, union_count =0;
  
  // 교집합의 수 체크하기
    for(let i = 0 ; i < intersection.length ; i++){
        let count1 = 0, count2 = 0;
        for(let j = str1.indexOf(intersection[i]) ; j < str1.length ; j++){
            if(str1[j]=== intersection[i])
                count1++;
           
        }
        for(let j = str2.indexOf(intersection[i]) ; j < str2.length ; j++){
            if(str2[j]=== intersection[i])
                count2++;
          
        }
      // 작은 수의 값을 교집합 수에 더해줌
        if(count1 < count2)
            inter_count += count1;
        else 
            inter_count += count2;
    }
  
  // 합집합 구하기
     for(let i = 0 ; i < union.length ; i++){
        let count1 = 0, count2 = 0;
        for(let j = str1.indexOf(union[i]) ; j < str1.length ; j++){
            if(str1[j]=== union[i])
                count1++;
        }
        for(let j = str2.indexOf(union[i]) ; j < str2.length ; j++){
            if(str2[j]=== union[i])
                count2++;
        }
       // 큰 수의 값을 합집합 수에 더해줌
        if(count1 < count2)
            union_count+= count2;
        
        else 
            union_count+= count1;
        
    }
   // 합집합이 공집합이거나 교집합이 없으면 1
    if((inter_count === 0 && union_count === 0) || union_count === 0)
        return 1 * 65536
    else // 소수점 버리고 반환
        return Math.floor(inter_count / union_count * 65536)
}

두번째 시도

// 문자열 가져올 수 있는 조합 반환 함수
function getStringCombinations(str) {
    // 대문자로 변환시키고
    const arr = str.toUpperCase().split('');
    const result = [];
    const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    for (let i = 0; i < arr.length - 1; i++) {
        if (alphabet.includes(arr[i]) && alphabet.includes(arr[i + 1])) result.push(arr[i] + arr[i + 1])
    }
    // 정렬해서 반환
    return result.sort();
}

function solution(str1, str2) {
    // 조합가져오기
    str1 = getStringCombinations(str1);
    str2 = getStringCombinations(str2);

    // 중복되지않게 일단 교집합과 합집합 원소들 가져오기
    const intersection = [...new Set(str1.filter((str) => str2.includes(str)))];
    const union = [...new Set([...str1, ...str2])];
    let intersectionCount = 0;
    let unionCount = 0;
   
 
    //교집합 원소의 수 -> 가장 적게 등장한 횟수를 더해주어야 함
    intersection.forEach((data) => {
        // str1,str2 각각에 대해 교집합 원소 시작 인덱스를 가져오고
        let str1Index = str1.indexOf(data);
        let str2Index = str2.indexOf(data);
        let count1 = 0;
        let count2 = 0;
        // 증가시키면서 몇번 등장하는지 파악
        while (str1[str1Index ] === data) {
            count1 += 1;
            str1Index += 1;
        }
        while (str2[str2Index] === data) {
            count2 += 1;
            str2Index += 1;
        }
        // 적게 등장한 수 더해주기
        intersectionCount  += count1 < count2 ?  count1 : count2;
    })
    // 합집합 -> 가장 많이 등장한 횟수를 더해주어야함
    union.forEach((data) => {
        // str1,str2 각각에 대해 합집합 원소 시작 인덱스를 가져오고
        let str1Index = str1.indexOf(data);
        let str2Index = str2.indexOf(data);
        let count1 = 0;
        let count2 = 0;
        // 증가시키면서 몇번 등장하는지 파악
        while (str1[str1Index ] === data) {
            count1 += 1;
            str1Index += 1;
        }
        while (str2[str2Index ] === data) {
            count2 += 1;
            str2Index += 1;
        }
        // 많이 등장한 수 더해주기
        unionCount += count1 > count2 ? count1 :  count2;
    })
    
    //공집합이거나 교집합이 없으면 65536반환하고
    // 그외에는 정수부만 출력
    return ((intersectionCount === 0 && unionCount === 0) || unionCount === 0) ? 65536 : Math.floor(intersectionCount / unionCount * 65536);
}
profile
즐기면서 정확하게 나아가는 웹프론트엔드 개발자 https://happhee-dev.tistory.com/ 로 이전하였습니다

0개의 댓글