재귀(Recursion)를 활용하면 코드가 매우 간결해진다. 하지만, 메모리를 많이 차지하는 단점도 있다. 재귀는 본인과 유사한 방식으로 항목을 반복 수행하는 과정(process)이다. 컴퓨터 프로그램에 대해서, 루프처럼 반복되는 명령어를 의미한다.
카운드다운 예제를 보면 처음 큰 숫자를 받은 함수가 있고, 이를 하나 줄인 함수가 있다. 조건이 만족되지 않아 쭉 큰 문제가 줄어들다가 마지막 1이라는 조건이 만족되면 프로그램 수행을 마치고 종료된다.
countdown <- function(i) {
cat(i, "\n")
if (i <= 1) {
cat("발사(Blast off) !!!")
} else {
countdown(i-1)
}
}
countdown(5)
## 5
## 4
## 3
## 2
## 1
## 발사(Blast off) !!!
차례곱을 while
루프를 활용하여 구할 수도 있지만, 재귀를 활용하여 코딩하게 되면 코드가 한결 간결하다. 역시, 재귀반복을 빠져나가는 기본사례 여기서는 x==1
인 경우 재귀반복을 마치고 차례곱 계산을 완료한다.
fact <- function(x) {
if (x == 1) {
return(1)
} else {
return(x*fact(x-1))
}
}
fact(5)
## [1] 120
재귀는 함수 콜스택과 밀접한 연관이 있다. 즉, 함수내에 함수를 실행할 경우 함수 내부의 함수가 실행을 완료할 때까지 기다린다. 따라서, 다음 greet
함수는 내부에 greet2
, bye
함수가 완료되어야 실행을 완료할 수 있다.
greet2 <- function(name) {
cat("요즘 어떻게 지내세요?", name, "님\n")
}
bye <- function() {
cat("다음에 봐요!")
}
greet <- function(name) {
cat("안녕하세요", name, "님\n")
greet2(name)
cat("작별인사를 할 준비...\n")
bye()
}
greet("정훈")
## 안녕하세요 정훈 님
## 요즘 어떻게 지내세요? 정훈 님
## 작별인사를 할 준비...
## 다음에 봐요!