티스토리 뷰

오늘은 재귀에 대하여 배웠고, 재귀를 이용한 

문제들을 푸는 시간을 가졌다.

 

문제를 푸는 도중에 가장 단순한 실수로 시간을 허비한 문제가 있어서 

기록으로 남겨보려 한다.

 

선물 상자에 대한 정보를 담은 배열과 문자열을 입력받아,

조건에 맞는 선물이 있는지 여부를 리턴하는 코드였다.

function unpackGiftbox(giftBox, wish) {
  // TODO: 여기에 코드를 작성합니다.

  let n = giftBox.length

  if(n===0 || wish.length===0) return false

  //giftBox 순회
  for(i=0;i<n;i++){
    //배열여부 확인
    if(giftBox[i]===wish) return true
    else if(Array.isArray(giftBox[i])){
      //값이 동일하면 true
      if(unpackGiftbox(giftBox[i],wish)) return true
    }
  }

  return false
}

 

해당 코드는 배열을 순회하며, 요소가 배열이면 재귀함수를 호출해주고

wish와 순회한 요소가 같다면 true를 리턴해주는 코드이다.

 

base case도 잘 나누어주었고

재귀함수도 순회 요소가 배열일 때 사용해주었는데, 시간초과가 나와서

3-40분 동안 코드를 고치고 틀린부분을 찾으려고 했지만, 찾을 수 없었다.

 

해결

페어와의 코드를 비교를 해도 변수명만 다르고 함수가 실행되는

로직은 동일하였다.

 

무엇이 문제인가 찬찬히 살펴보면서 코드를 비교하였는데,,,,

 

기프트 박스를 순회 시 let 선언 없이 반복문을 실행한 것이었다.

  //giftBox 순회
  for(i=0;i<n;i++){

 

평소에도 반복문을 사용할 때, let 선언을 하지않아도 문제 없이 코드가 작동하여서 의아했다.

하지만 재귀함수를 생각해보니

let 선언이 없다면 i는 var로 전역변수로 선언이 되고,

하위 스코프인 재귀함수에서는 계속해서 전역변수에 접근하여 i의 값이 계속해서 바뀌게 되고

시간초과에 이르게 된 것이었다.

 

따라서 let i=0 을 설정하여 상위 스코프의 i를 변경하지 않게 만드니, 문제가 해결이되었다.

 

 

 

function unpackGiftbox(giftBox, wish) {
  // TODO: 여기에 코드를 작성합니다.

  let n = giftBox.length

  if(n===0 || wish.length===0) return false

  //giftBox 순회
  for(let i=0;i<n;i++){
    //배열여부 확인
    if(giftBox[i]===wish) return true
    else if(Array.isArray(giftBox[i])){
      //값이 동일하면 true
      if(unpackGiftbox(giftBox[i],wish)) return true
    }
  }

  return false
}​

 

결론

작은 차이인데도, 전혀 다른 결과를 만드는 것을 보고

변수, 상수를 선언하는 습관을 생활화 해야겠다고 생각이 들었다.

var는 절대 사용하지 말자! 예상치 못한 오류를 만나게 된다(나처럼)

 

'코드스테이츠' 카테고리의 다른 글

TIL 23.02.15  (0) 2023.02.15
TIL 23.02.14 + (innerText 와 textContent)  (0) 2023.02.14
TIL 23.02.10 & Section2 회고  (0) 2023.02.10
TIL 23.02.09 + 오류  (0) 2023.02.09
TIL 23.02.08  (0) 2023.02.08
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함