재귀 함수는 일반적으로 "분할 정복을"을 수행 -strategy에서
.
<=> max(max(a, b), max(c, d))
귀하의 알고리즘은 다음 파티션 선택 :
임의로, 모든 지역 최대의 최대 값을 찾아 우리가 그 목록을 분할 할 수
max(a, b, c, d)
목록의 최대를 찾으려면
<=> max(a, max(b, c, d))
max(b, c, d)
에 대해서도 마찬가지입니다. 호출 그래프 :
max(a, b, c, d)
max(b, c, d)
max(c, d)
max(d)
max(d)
에서 알고리즘은 더 이상 발생하지 않습니다. 대신 기본 사례 (루프의 종료 조건에 해당)입니다. max(d)
은 d
을 반환합니다. 우리는 지금이 아이디어는 인코딩 할 수있는 다른 많은 방법이있다
호출 스택을 통해 다시 우리의 방식으로 작동합니다, 우리의 첫 번째 값에리스트의 나머지의 최대 값을 비교하여 총 최대를 찾을 수 있습니다.
sub maxNum {
my $current_max = pop;
while(@_) {
my $compare = pop;
$current_max = $compare if $compare > $current_max;
}
return $current_max;
}
이렇게하면 재귀 적 솔루션과 같은 순서로 요소를 비교합니다.
최대 값을 찾는 것은 접기 작업 (일명 reduce
)으로 간주 할 수 있습니다. 우리는 다음과 같은 파티션 않는 재귀 함수를 쓸 수 있습니다 :이 은 매우 복잡 보이는
max(a, b, c, d)
<=> max(max(a, b), c, d)
<=> max(max(max(a, b), c), d)
을하지만 우아한 해결책에 이르게 : 값이 즉시이라고한다 반환
sub maxNum {
return $_[0] unless $#_; # return if less than two elems
my ($x, $y) = splice 0, 2, @_; # shift first two elems from @_
my $max = $x > $y ? $x : $y; # select larger
return maxNum($max, @_); # recurse
}
함수 호출 꼬리 전화. 특별한 goto &subroutine
표현식을 사용하여 더 효율적으로 만들 수 있습니다. 그러나 인수 목록을 수동으로 설정해야합니다.
sub maxNum {
return shift unless $#_; # base case: return on one argument
my ($x, $y) = splice 0, 2, @_; # take the first two elems from start
unshift @_, $x > $y ? $x : $y; # put the larger one back there
goto &maxNum; # recurse with tail call
}
처음에 어떻게 호출됩니까? –
재귀에 대한 이해가 잘못되었습니다. 재귀 함수에 대한 이전 호출은 나중에 모든 재귀 호출이 완료 될 때까지 본질적으로 차단됩니다. – chepner