recursion & memoization 21.04.19


memoization : 프로그래밍(ex : 재귀 호출) 시 반복 되는 결과를 메모리에 저장해서 다음에 같은 결과가 나올 때 이전에 저장한 메모리에서 불러와서 실행하는 방법. (속도가 빠르다.)

memoization 예제 코드

피보나치 수열
  • recursion
let fibo = (number) => {
    // base case
    if (number < 2) {
        return number;
    } 
    // recursive case
    return fibo(number-2) + fibo(number-1)
}
// 위 코드를 삼항 연산자로 한줄로 작성할 수도 있다.
let fibo = (n) => {
    return n < 2 ? n : fibo(n-2) + fibo(n-1)
}

fibo(10) // 55

일반적인 재귀 함수로 fibonacci 수열을 구현하면 중복되는 계산 때문에 시간이 오래걸린다.

시간 단축을 위해 memoization이 필요하다.

  • recursion + memoization
// 계산 값을 저장하기 위해 memo 배열 사용.
// 초기 값은 피보나치 수열의 0번째와 1번째 값을 저장.
let memo = [0, 1]

let fiboMemo = (n) => {
    // 만약 memo의 n번째 인덱스의 type이 숫자가 아니라면
    // (즉, n번째 피보나치 수열이 메모에 저장되어 있지 않다면)
    if (typeof memo[n] !== 'number') {
        // memo[n]의 값을 재귀를 통해 저장해준다.
        memo[n] = fiboMemo(n-1) + fiboMemo(n-2);
    }
    return memo[n]
}

성능 상세 비교 recursion vs recursion + memoization

  • recursion
let count = 0;
let fibo = (number) => {
    count++;
    console.log('재귀 횟수:', count);
    // base case
    if (number < 2) {
        return number;
    } 
    // recursive case
    return fibo(number-2) + fibo(number-1)
}

fibo(20); // 재귀 횟수 : 301번
  • recursion + memoization
let memo = [0, 1];
let count = 0;
let fiboMemo = (n) => {
    if(typeof memo[n] !== 'number') {
        count++;
        console.log('재귀 횟수: ', count)
        memo[n] = fiboMemo(n-2) + fiboMemo(n-1);
    }
    return memo[n]
}

fiboMemo(20); // 재귀 횟수: 19
fiboMemo(50); // 재귀 횟수: 49





© 2020.11. by creamer

Powered by CREAMer