본문 바로가기

프로그래머스/구현

[문자열] 프로그래머스 '뉴스 클러스터링' - js

반응형

1. 문제

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

2. 코드

처음 푼 코드)

혼자 별 짓을 다했다. 테케도 다 통과되고 반례도 다 통과되는 것을 확인했는데 도대체 뭐가 문제여서 4,6,7,9,11 번이 통과되지 않는 것인지 모르겠다. 프로그래머스는 다 좋은데 내가 틀린 케이스를 좀 볼 수 있었음 좋겠다 ㅠㅠ 답답하다! 밑의 코드는 굳이 설명도 안하고싶다 ㅋㅋㅋㅋ진짜 별 짓 다한 코드이기 때문에.. 한 세 시간 삽질했나?ㅠㅠ 그래도 끝까지 붙들고 포기하지 않은 노력은 가상하다^^

function solution(str1, str2) {
    let answer = 0, alpha =["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"],
    one = [], two = [];
    str1 = str1.toLowerCase();
    str2 = str2.toLowerCase();
    
  for(let i=0;i<str1.length;i++){
    if(alpha.includes(str1[i]) && alpha.includes(str1[i+1])) one.push(str1[i]+str1[i+1])
  }

  for(let i=0;i<str2.length;i++){
    if(alpha.includes(str2[i]) && alpha.includes(str2[i+1])) two.push(str2[i]+str2[i+1])
  }
  
  if(one.length > two.length){
    let newOne = one.slice();
    one = two.slice();
    two = newOne;
  }
  one.sort(); two.sort();
  
  let newTwo = two.slice();
  let temp = [];
  
  for(let i=0;i<one.length;i++){
    if(newTwo.includes(one[i])) {
      newTwo.splice(one[i],1);
      temp.push(one[i])
    }
  }
  
  let same = temp.slice();
  let combine = [];
  for(let i=0;i<one.length;i++){
    if(temp.includes(one[i])) temp.splice(one[i],1);
    combine.push(one[i]);
  }
  temp = same.slice();
  for(let i=0;i<two.length;i++){
    if(temp.includes(two[i])) temp.splice(two[i],1);
    else combine.push(two[i])
  }
  
  if(!one.length && !two.length) answer = 1;
  else if(same.length === combine.length && new Set(one).length === new Set(two).length) answer = one.length / two.length;
  else answer = same.length/combine.length;
    
    return Math.floor(answer * 65536);
}

정답)

이 풀이의 핵심은 교집합을 구할 때 splice를 사용하는 것이다.

splice는 mutable하고, slice와 substr은 immutable 하다. 코테에서 잘 활용하자.

const solution = (str1, str2) => {
  //각각의 원소 쌍을 구하는 과정 Set으로 구현할 수 없어서 Array 사용
  str1 = str1.toUpperCase();
  str2 = str2.toUpperCase();
  const arr1 = [];
  const arr2 = [];

  for (let i = 0; i < str1.length - 1; i++) {
    const str = str1.substr(i, 2);
    if (str[0] >= "A" && str[0] <= "Z" && str[1] >= "A" && str[1] <= "Z") arr1.push(str);
  }
  for (let i = 0; i < str2.length - 1; i++) {
    const str = str2.substr(i, 2);
    if (str[0] >= "A" && str[0] <= "Z" && str[1] >= "A" && str[1] <= "Z") arr2.push(str);
  }

  //교집합과 합집합을 구하기
  const intersection = [];
  const union = [];
  for (let i = 0; i < arr2.length; i++) {
    if (arr1.includes(arr2[i])) {
      intersection.push(arr1.splice(arr1.indexOf(arr2[i]), 1));
    }
    union.push(arr2[i]);
  }
  // arr1 교집합에 포함되지 않은 나머지 요소들 합집합에 넣기
  for (let i = 0; i < arr1.length; i++) {
    union.push(arr1[i]);
  }
    
  if (intersection.length === 0 && union.length === 0) return 65536;
    
  return Math.floor(65536 * (intersection.length / union.length));
};

 

아 이렇게 깔끔한 코드로 해결될 수 있는 것이였구나..이렇게 간단하게 할 수 있는걸!! 왜 난 저걸 못했는가~! 분명 접근 방법은 비슷한 것 같은데... 뭐가 문제인지 파악하고 싶다!!

여튼 교집합, 합집합 문제가 나올 때 잘 기억해뒀다가 써먹어야겠다.

복기

6/1
반응형