[SEB_FE] 재귀 코플릿(7,9,13-15)

seunghyo·2023년 4월 11일
0

SEB_FE

목록 보기
21/38

07. arrLength


function arrLength(arr) {
  // TODO: 여기에 코드를 작성합니다.
  if(빈 배열일때){return 0} //배열이 비어있을 때 길이는 0 , 
  return 1+arrLength(arr.slice(1));//모든요소의 길이(1)씩 빼주고 마지막 배열 빌때 0을 더해주면 배열의 길이
}

arr.slice(num)은 idx가 num인 것부터 끝까지의 배열이다. 1씩 더해주고 slice된 배열을 재귀해주면 결국 arr.length의 총합을 구할 수 있다.

09. take


수(num)와 배열을 입력받아 차례대로 num개의 요소만 포함된 새로운 배열을 리턴

function take(num, arr) {
  // TODO: 여기에 코드를 작성합니다.
  if(num이 arr의 길이보다 길거나 같을 때){
    return arr
  }
  if(num === 0){return []}
  newarr = 0번째 인덱스만 배열의 요소로 갖는 새 배열
  newarr와 take(num-1,arr.slice(1))를 concat한 배열을 리턴한다.;//num 하나 차감하고, 재귀 
  //take(2, [1, -2, 1, 3]) , newarr = []
  //take(1, [-2,1,3]) , newarr = [1]
  //take(0, [1,3]) , new arr = [1,-2]

}

직접 트리를 그려보면 이해하기 편하다.

13. findMatryoshka


러시아 전통인형 마트료시카에 대한 정보를 담은 객체와 수를 입력받아 조건에 맞는 인형이 있는지 여부를 리턴

코플릿을 풀때는 늘 이게 맞나..? 하면서 풀어간다.일단 고민하지 않고 생각나는대로 코드를 적다가 막히면 그제야 수도코드를 적는 편...미리 고민하고 풀다 막히면 멘붕이 와서 이런 습관이 생겼다ㅠ_ㅠ

function findMatryoshka(matryoshka, size) {

  //if(Object.keys(matryoshka).length === 0){
    //return false;
  //}
  if(matryoshka.size === size){
    return true;
  }
  else if(matryoshka.size > size && matryoshka.matryoshka){
    return findMatryoshka(matryoshka.matryoshka,size);
  }
  else return false
}

객체가 비었는지 확인하는 코드를 적지 않아도 통과가 된다. 테스트 마지막에 else 조건을 달아줘서 그런거 같다. 미리 확인하면 더 시간 절약이 되지 않을까..?:ㅇ(일단 주석 처리해줌).

//입력 예시
const matryoshka = {
  size: 10,
  matryoshka: {
    size: 9,
    matryoshka: null,
  },
};

사이즈는 점점 작아지는 형태, 즉 마트료시카다. 사이즈가 같으면 true , 그밖에 사이즈가 크다면 결국 다음 객체는 작은 마트료시카일테니까... 다음 마트료시카가 있다면 그 마트료시카를 검사(findMatryoshka(다음 마트료시카))한다. 만약 다음 마트료시카가 없거나 사이즈가 크지 않다면 결국 없을테니 false를 return한다.

14. unpackGiftbox


선물 상자에 대한 정보를 담은 배열과 문자열을 입력받아 조건에 맞는 선물이 있는지 여부를 리턴

이번 문제는 for, while 사용이 가능했다. 이것 자체가 힌트가 되었던 것 같다.(이런 꼼수를 쓰면 안되는데...^^) 내가 생각한 것은 giftbox 배열을 for문으로 돌면서 검사해주는 것이었다. 배열일 때와 배열이 아닐때를 나누어 검사해주면 된다고 생각했다

//입력예시
const giftBox = ['macbook', 'mugcup', ['eyephone', 'postcard'], 'money'];

Array.isArray를 이용해 배열일때 아닐때를 구분했다. 배열이 아닐때는 그냥 wish와 맞는지 확인하고 true를 리턴. base case일때는 자동 false다. 그 전 문제까지는 base case를 따로 고려 안했는데 일단 base case를 설정해놓고 리커시브를 작성하는게 좋은 것 같다..

function unpackGiftbox(giftBox, wish) {
  // TODO: 여기에 코드를 작성합니다.
  for(let i = 0; giftBox.length>i; i++){
    
    if(Array.isArray(giftBox[i])){ //배열일때
      let wishedgift = unpackGiftbox(giftBox[i],wish)
      if(wishedgift === true){return true}
    }
    if(giftBox[i]=== wish){ //배열이 아닐때
        return true
      }
  }

  return false;
}

배열일 때는 그 요소에 다시 unpackGiftbox를 해준다 만약 그 배열 내에 wish가 있다면 true가 리턴되어 결국 바깥 배열도 true가 되도록 wishedgift 를 설정해주었다. 뭔가 얼렁뚱땅 푼 느낌이기도 한데...;;

💡Reference code

첫번째 레퍼런스는 내 코드와 유사했다. 풀이는 총 3개가 있었는데 2번만 풀어보자


function unpackGiftbox(giftBox, wish) {
   // recursive case
   let anotherBoxes = [];
   for (let i = 0; i < giftBox.length; i++) {
     if (giftBox[i] === wish) {
       return true;
     } else if (Array.isArray(giftBox[i])) {
      anotherBoxes = anotherBoxes.concat(giftBox[i]);
     }
   }

   if (anotherBoxes.length > 0) {
     return unpackGiftbox(anotherBoxes, wish);
   }
 return false; 
}

anotherBoxes 라는 새 배열을 추가해주어 배열인 요소들을 다 anotherBoxes에 concat 해주었다. 결국 2차원 배열을 1차원 배열로 만들고, 이것을 다시 unpackGiftbox해준다. 난 각 요소가 배열일 경우에는 그 배열만 검사했지만 이건 합쳐서 검사한 것의 차이가 있다. (효율의 차이가 있을까?)

15. flattenArr


다차원 배열을 입력받아 1차원 배열로 변환하여 리턴

제일 까다로웠던 문제..일단 보고 포스트잇에 대강 output이 들어왔을 때 어떤 과정으로 진행되야할까...고민했다. 내가 생각한 것은 새 배열을 생성하고, 배열 안 요소들을 배열인 경우 분해하여 push해주고, 아닌 경우는 그냥 push해주는 것이었다. 이번에도 for문을 사용했다.

function flattenArr(arr) {
  // TODO: 여기에 코드를 작성합니다.
  //조건 1 output = flattenArr([[1], 2, [3, 4], 5]);
  if(arr.length === 0){return []}
  let newarr = [];
  for(let i =0; arr.length>i; i++){
    if(Array.isArray(arr[i])){
      let tmp = flattenArr(arr[i]); 
      //arr[0]일때 tmp 값은 [1]
      //arr[2]일때 tmp 값은 [3,4]
      //push 할 때 요소만 넣어줘야하므로 Spread Syntax 사용하여 push
      newarr.push(...tmp);
    }
    else{ newarr.push(arr[i]);}
  }
  return newarr;
}

중간에 잠시 헤맸는데 push를 할때 배열을 넣어주어(ㅜㅜ) 자꾸 오류가 뜨는 것이었다. 오류로그를 보고 그것을 고쳐주니 잘 돌아갔다. array일 경우에는 계속 분해되어 flattenArr의 값은 결국 일차원 배열이 된다.

💡Reference code


function flattenArr(arr) {
  // base case
  if (arr.length === 0) {
    return [];
  }

  // recursive case
  const head = arr[0];
  const tail = arr.slice(1);
  if (Array.isArray(head)) {
    return flattenArr([...head, ...tail]);
    //배열을 분해
  } else {
    return [head].concat(flattenArr(tail));
    //head는 배열이 아닌것이 확인, 나머지 tail을 검사
  }
}

0개의 댓글