프로그래밍/Js

[es6] 배열의 합 (꼬리물기 재귀함수 <--> for문으로 변경)

소행성왕자 2023. 10. 17. 18:37

아래 두개의 코드는 두 가지 다른 방법으로 배열의 합을 계산하는 두 가지 함수를 포함하고 있습니다.

하나는 꼬리물기재귀(tail recursion)를 사용하고 다른 하나는 for 루프를 사용합니다.

각 함수와 코드 블록에 대한 설명은 다음과 같습니다:

꼬리물기 재귀함수

    const _sum = (arr, i, acc) => i > -1 ? _sum(arr, i-1, acc = acc + arr[i]) : acc;
    const sum = (arr) => _sum(arr, arr.length-1, 0);
    
    console.log('꼬리물기재귀 : '+ sum([1,2,3,4]));

 

_sum 함수는 재귀 함수로, 배열 arr, 현재 인덱스 i, 및 합산기 acc를 받습니다. 

재귀적으로 배열을 합산하며, i가 -1보다 큰 경우 계속해서 자신을 호출하면서 값을 누적합니다. 

i가 -1 이하인 경우 재귀가 종료되고 누적된 acc 값이 반환됩니다.

sum 함수는 _sum 함수를 호출하며 배열의 첫 번째 요소부터 시작하여 합계를 계산합니다.

console.log를 사용하여 꼬리물기 재귀 방식으로 계산된 합계를 출력합니다.

for 루프

    const sum2 = arr => {
        let acc = 0;
        let i = arr.length-1;
        for(i; i>-1; i=i-1) {
            acc = acc + arr[i];
        }
        console.log('for문:'+acc);
    };
    sum2([1,2,3,4]);

sum2 함수는 for 루프를 사용하여 배열의 합을 계산합니다. 

먼저 acc 변수를 0으로 초기화하고, i 변수는 배열의 끝에서 시작하여 역순으로 진행합니다.

for 루프를 사용하여 각 요소를 누적하고, 결과는 acc에 누적됩니다.

console.log를 사용하여 for 루프를 통해 계산된 합계를 출력합니다.

두 가지 방법은 모두 배열의 합을 계산하는데 사용될 수 있으며, 하나는 재귀 함수를 사용하고 다른 하나는 for 루프를 사용하는 방식입니다. 

두 방법 모두 올바른 결과를 생성하지만 꼬리물기 재귀 함수는 스택오버플로우 함정이 있으므로 

꼬리물기 재귀함수로 먼저 작성한뒤

기계적으로 for 루프로 변환하면 복잡한 for 문도 정복할수 있습니다.


위 코드를 더 좋은 코드로 바꿔봅시다.

if(1) {
    const _recursive = (arr, i, acc) => i<=arr.length ? _recursive(arr, i+1, acc+i) : acc;
    const recursive = arr => _recursive(arr, 0, 0);
    console.log('꼬리물기재귀:'+recursive([1,2,3,4,5,6,7,8,9,10]));

    const sum = arr => {
        let i=0, acc=0;
        while(i<=arr.length) {
            acc = acc+i
            i = i+1;
        }
        return acc;
    }
    console.log('while:'+sum([1,2,3,4,5,6,7,8,9,10]));
}

결과
꼬리물기재귀 : 55
while : 55