2009-02-26 7 views
3

단일 루프가있는 메소드를 재귀 적 메소드로 자동 리팩토링하는 툴을 알고 있습니까?루프를 재귀 적 방법으로 자동 리팩토링 하시겠습니까?

이것은 교육용입니다.

+0

홀수 일반적으로 당신은 다른 방향으로 가고 싶어합니다. 반복적으로 재귀 적으로 가고 싶습니다. – dwc

+0

흥미로운 질문입니다.이 문제를 해결하기위한 알고리즘 설명이 있습니까? – pgras

답변

4

일반적으로 리팩토링은 성능을 높이고, 줄이려하지 않으므로 (루프 대신 재귀 적 방법을 사용할 때) 이러한 도구가 존재한다고 생각하지 않습니다. 교육 목적을위한 것이라면, 학생들이 그렇게 할 수있는 도구를 만들지 않겠습니까? 이렇게하면 재귀와 파싱을 동시에 배울 수 있습니다.

재귀를 자동화 할 수 있는지 여부는 잘 모르겠지만 여기서는 변형이 어떻게 보일 것입니다. 의 데모를 위해, 의사 코드에서 루프에 대한 일반적인 보자 :

loopFunc() // method (could return a value or not) 
{ 
    for (initialization ; // Sets the context 
     test ;   // Test continuation wrt the context 
     counting_exp  // Update the context after each iteration 
     ) 
    { 
     loop_body 
    } 
} 

를 루프는 네 부분으로 구성되어있다 : initialization, 컨텍스트 (일반적으로 변수)를 초기화; test, 루프를 완료했는지 여부를 확인하는 부울 식입니다. counting_exp은 각 반복 후에 수행되는 명령문입니다. 마지막으로 loop_body으로, 각 반복에서 실행되는 연산을 나타냅니다. 초기화 하나, 다른 하나는 실제로 루프 수행 :

이 방법의 재귀 버전은 두 부분으로 분해되어야한다 충분히 100로

recFunc() 
{ 
    initialization  // Sets the context 
    innerRecFunc(context) // We need to pass the context to the inner function 
} 

innerRecFunc(context) 
{ 
    if not test then return // could return a value 
    else 
    { 
     loop_body    // Can update context 
     counting_exp   // Can update context 
     innerRecFunc(context) // Recursive call (note tail-recursion) 
    } 
} 

내가 문제에 대해 생각하지 않았다을 이것은 모든 경우에 효과가있을 것이라고 확신하지만, 단순한 루프의 경우 이것이 정확해야합니다. 물론이 변환은 다른 유형의 루프에도 쉽게 적용 할 수 있습니다 (while, do while).

+0

그러나 모든 리펙토링은 동등하고 반대 리팩토링을 사용합니다. –

2

the halting problem의 변형을 좋아하는 것으로 보아도 일반적인 의미에서 가능하다는 점을 확신 할 수 없습니다.

+0

그러나 모든 반복 알고리즘은 재귀 알고리즘으로 변환 될 수 있으며 그 반대의 경우도 마찬가지입니다. 아니면 질문의 "자동"부분에 대해 이야기하고 있습니까? –

+0

일반적으로 두 프로그램이 같은지 여부를 결정할 수는 없지만 등가성을 유지하는 변환 집합을 가질 수는 있습니다. 가능한 스택 오버플로를 무시하면 알고리즘을 반복적에서 재귀 적으로 변경해야합니다. –

+0

일반적으로 일반적인 의미에서는 바람직하지 않습니다 (부작용을 생각하십시오).하지만 유용한 하위 집합 만 지원하면됩니다. –

0

가르치는 목적으로이 작업을 수행하는 경우 매우 제한된 경우에 대해 수행 할 수 있다고 생각합니다. 그래서 당신은

myMethod() { 
    // startcode 
    for (init,cond,incr) { 
    // loopcode 
    } 
    //endcode 
} 

을 가져다

myMethod() { 
    //startcode 
    init; 
    recursive(value); 
    //endcode 
} 
recursive(value) { 
    if (!cond) { 
    return 
    } else { 
    //loopcode 
    incr; 
    recursive(value); 
} 

난 당신이 자신의 의사를 정렬 할 수 있습니다 확신에 변형 뭔가를 작성할 수 있습니다.