어제는 재귀란 무엇인지 재귀함수를 호출할때 호출스택에서는 무슨일이 일어나는지를 살펴보았다. 오늘은 팩토리얼을 재귀적으로 구현하는 방법에 대해서 이야기하고자 한다.
function countUp(param){
var num = param;
if(num >= 10){
console.log("done");
return;
}
console.log(num);
num++;
countUp(num);
}
위의 코드는 어제 보았던 재귀적으로 작성한 countUp함수이다. num의 증가는 10에서 멈추도록 중간에 중단점을 두었고, console.log()로 값을 체크하며 중단점에서 return만 두어 값을 넘기지는 않은 채로 끝나도록 구현을 했다. 이 재귀함수를 조금 수정해서 다음과 같은 모습으로 만들어 봤다.
function countUp(num){
console.log(num);
if(num >= 10) return;
num++;
return countUp(num);
}
이렇게 return에서 함수를 다시 호출하는 것으로 코드가 한층 더 짧아진 것을 확인할 수 있다. 오늘은 이 방식으로 팩토리얼을 재귀적으로 만드는 연습을 할 것이다.
팩토리얼은 기억날지 모르지만 우리가 모두 중등 수학시간에 배웠던 것이다. 숫자뒤에 !을 붙여서 표기하는데 3!라면 3팩토리얼이라고 읽고 수식으로 3x2x1을 나타낸다.
3!을 코드로 구현한다면 과연 어떤 모습이 될까? 먼저 재귀를 사용하지 않고 for루프를 이용해 팩토리얼을 구현해 보았다.
function test(num){
var total = 1;
for(let i = 1; i<=num; i++){
total *= i;
}
return total;
}
이렇게 for루프를 이용하여 구현한 test함수에 3을 넣어 계산하게 하면
total * 1 //total = 1
total * 2 //total = 2
total * 3 //total = 6
//return 6
다음과 같은 계산과정을 거쳐 6이 반환된다. 이번에는 이 함수를 재귀적으로 바꿔보도록 하겠다.
function test(num){
if(num === 1) return 1;
return num*test(num-1);
}
짜잔~ 이렇게 훨씬 더 간결하게 구현할 수 있다 계산 과정은 다음과 같다. 어제 공부했던 것을 떠올리면 함수내부에서 함수를 호출하면 그 함수가 끝나거나 return 값이 반환될 때까지 호출스택에서 사라지지 않는다는 것을 기억해 낼 수 있을 것이다. 그렇다면 계산 순서는 다음과 같아진다.
3 * test(2) //3*2 return 6
2 * test(1) //2*1 return 2
num === 1 //return 1
이와같이 중단점까지 함수가 호출된 뒤로 그 다음부터 값이 리턴되면서 전달된 값으로 계산이 진행되어 마지막에 6이라는 값이 최종적으로 리턴이 된다. 이런 방식으로 재귀는 동작한다. 만약 여기서 더 큰 숫자를 구하기 위해 인자로 입력한다면 더 많은 함수가 호출되어 스택에 쌓일 것이다.