2010-12-12 7 views
9

재귀 호출을 쉽게 구현하거나 원치 않는 설정에서 기존 코드를 다시 작성합니다. (그리고 Fortran 77에서 알아야 할 필요가있다.) 나는 처음부터 스택을 만들어서 필요한 호출을 추적하는 방법에 대해 생각해 보았다. 그러나 이것은 kludgy처럼 보였고, 배열에 메모리를 할당하지는 않았다. 재귀가 깊지 않습니다. (Fortran 77이 동적 배열 크기 조정을 지원하지 않는다고 확신하지 못합니다.) 분명히 재귀 함수를 사용하여 스택에 공간을 낭비하지 않으면 서 재귀 적으로 재 작성하는 방법에 대한 일반적인 해결책에 대한 다른 제안 사항은 무엇입니까?재귀 호출을 사용하지 않고 재귀 함수 다시 쓰기

많은 감사, 옛 문화 체육 관광부

+2

분기하지 않으면 보통 간단한 루프로 다시 작성할 수 있습니다. 분기하는 경우 일반적으로 스택이 필요합니다. – CodesInChaos

+1

@CodeInChaos : 분기하지 않는 재귀 함수는 정의 상 반환하지 않습니다. –

+0

단어 분기를 오용 한 것으로 추측합니다. 나는 그 자체를 여러 번 호출하는 것을 의미하므로 호출 그래프는 가지가있는 나무가된다. 그리고 그것은 내 경험 일 뿐이며 항상 사실이 아닙니다. – CodesInChaos

답변

14

코드가 꼬리 재귀 (즉, 함수가 직접 다른 처리없이 모든 재귀 호출의 결과를 반환한다) 다음은 스택없이 명령 적 기능을 재 작성하는 것이 가능 사용하는 경우 :

function dosomething(a,b,c,d) 
{ 
    // manipulate a,b,c,d 
    if (condition) 
    return dosomething(a,b,c,d) 
    else 
    return something; 
} 

속으로 :

function dosomething(a,b,c,d) 
{ 
    while (true) 
    { 
    // manipulate a,b,c,d 
    if (condition) continue; 
    else return something; 
    } 
} 

꼬리 재귀가 없으면 스택 (또는 유사한 중간 저장 장치)을 사용하는 것이 유일한 해결책입니다.

function fib(n) 
{ 
    // valid for n >= 0 
    if (n < 2) 
     return n; 
    else 
     return fib(n-1) + fib(n-2); 
} 

그러나 메모이 제이션없이 걸리는 O (EXP^N) O와 연산 (N) 스택 공간 : 루프로 쓸 수

+0

이것은 내가 생각한 것과 비슷하지만 말로 표현할 수 없습니다. 따라서 필자의 경우에는 세트의 다른 요소와의 관계를 테스트 할 필요가있는 요소의 데이터 세트가 있습니다. 모든 항목의 데이터 구조를 전달할 수 있지만 추가 처리가 필요하기 때문에 스택이 필연적이라고 생각합니까? –

+0

에 따라 다릅니다.코드가 대부분 "모든 쌍 (a, b)에 대해 P (a, b)가 참이면 F (a, b)를 실행"하면 모든 쌍을 반복적으로 반복하여 빠져 나갈 수 있습니다. –

2

대부분의 재귀 함수는 쉽게 공간 낭비에 관해서는, 루프로 다시 작성할 수 있습니다 - 재귀 많은 (전부는 아니지만) 알고리즘이 실제로 그런 종류의에 의존하기 때문에, 기능에 따라 달라집니다 저장소 (그러나 루프 버전은 일반적으로이 경우에도 더 효율적입니다).

+0

스택에 공간이 필요없는 재귀 함수를 표시하는 데주의해야합니까? 그 주장에 대해서조차? –

+1

@Nikita Rybak : 인라인 꼬리 재귀 함수;) –

+0

@Victor 예,하지만 재 작성된 형식입니다. Ofir은 스택 메모리가 필요없는 재귀 함수가 있다고 주장합니다. 그래서, 나는 호기심이 많다. –

3

고전 재귀 함수는 피보나치 함수이다.

은 그것은 다시 작성할 수 있습니다 :

function fib(n) 
{ 
    if (n < 2) 
     return n; 
    var a = 0, b = 1; 
    while (n > 1) 
    { 
     var tmp = a; 
     a = b; 
     b = b + tmp; 
     n = n - 1; 
    } 
    return b; 
} 

하지만이 기능은 자동 프로세스에 일반화 될 수 있는지 확실하지 않습니다, 어떻게 작동하는지에 대한 지식을 포함한다.