2012-02-16 4 views
2

I 재귀 여기 재귀 피보나치

C.

에 포크를 이용하여 소정의 INT N에서 생성 피보나치 수를 계산하는 기능을 쓰려고있어 함수 사양이다 : doPrint가 true 인 경우 인쇄하십시오. 그렇지 않으면 상위 프로세스에 제공하십시오. 솔루션은 재귀 적이어야하며 각 호출에 대해 새 하위를 분기해야합니다. 각 프로세스는 doFib()를 정확히 한 번 호출해야합니다. 메소드 서명은 변경할 수 없습니다. 도우미 기능은 사용할 수 없습니다. 그러나이 내 수정 된 코드입니다, Recursive Fibonacci using Fork (in C)

불행하게도, 내가 마지막 게시물에 문제에 대한 해결책을 생각하지 :

이 질문의 연속이다. 나는 그것을 알아 냈다고 생각했으나 (psuedo code wise) 코드는 아직 몇 조각인지 확신 할 수 없다.

이 시점에서, 이것은 내 오락을위한 것입니다. 이것은 숙제가 아니며 수업이 끝난 후 다시 수업에 적용되지 않습니다.

static pid_t root_pid; 

// Function to return exit code for PID 
static int exitcode(pid_t pid) 
{ 
    pid_t retpid; 
    int status; 

    retpid = waitpid(pid, &status, 0); 
    if (pid != retpid) 
    { 
     printf("waitpid error\n"); 
    } 

    return WEXITSTATUS(status); 
} 

static void doFib(int n, int doPrint) 
{ 
    root_pid = getpid(); 

    pid_t pid1; 
    int status1; 

    pid_t pid2; 
    int status2; 

    if(n < 2) // Base case, exit back to parent? 
    { 
     exit(n); 
    } 
    else // if not base case, fork child processes 
    { 
     pid1 = fork(); 
     if (pid1 == 0) // Child Process 1 (for fib(n-1)) 
     { 
      doFib(n-1, doPrint); 
      exit(n-1); 
     } 
     else if (pid1 > 0) // Parent Process 
     { 
      pid2 = fork(); 
      if (pid2 == 0) // Child Process 2 (for fib(n-2)) 
      { 
       doFib(n-2, doPrint); 
       exit(n-2); 
      } 

      // Get value from child process 1 
      status1 = exitcode(pid1); 
      // Get value from child process 2 
      status2 = exitcode(pid2); 

      // When to print? 
      if (getpid() == root_pid) 
      { 
       int result = status1 + status2; 
       if (doPrint) 
       { 
        printf("%d\n", result); 
       } 
       else 
       { 
        exit(result); 
       } 
      } 
     } 
    } 
} 

몇 가지 질문 ...

  1. 내가 각각의 자식 프로세스에 대한 이러한 기능 모두를 호출해야합니까?

    doFib(n-1, doPrint); exit(n-1); 
    
  2. 처음의 기본 사례가 맞습니까? (n < 2)
  3. 내 기본 케이스가 맞습니까? (인쇄시기)

도움 주셔서 감사합니다.

+0

을, 당신은 것을 고려해야한다 피보나치 문제에 대한 재귀 적 해결책은 결과를 얻는 데 아주 나쁜 방법이다. 왜냐하면 그것은 무시 무시하게 비효율적이다. – Pointy

+0

@ Pointy 두 센트를 감사하게 생각하십시오. 중간 고사를 준비하기 위해 작성한 일련의 코딩 문제에서 비롯된 것이 었습니다. 적어도 저를 귀찮게 해드 렸지만, 교육적 목적을위한 것이라고 확신합니다. – CODe

답변

1

"인쇄 할 시점"에 대한 대답은 실제로 인쇄 할 대상으로 내려갑니다 ... 최종 답을 인쇄하기 만하면, 실제로있을 때를 나타내는 플래그가 필요할 것입니다 루트 부모 프로세스를 사용하고 if 문을 사용하여 실제로 루트 부모인지 테스트하여 하나의 숫자 만 인쇄합니다. 다른 한편으로 전체 시퀀스를 최종 번호까지 인쇄하려면 if 문이 필요하지 않습니다.

예를 들어, 좋은 플래그 값은 루트 프로세스의 PID입니다. 별도의 하위 프로세스를 분기하기 전에 먼저 main()의 첫 번째 행에 root_pid이라는 전역 변수에 저장할 수 있습니다. 그런 식으로 모든 하위 프로세스는 root_pidif 문에 대해 동일한 값을 가지므로 간단히 if (getpid() == root_pid)이 될 수 있습니다.

그래서 이런 일을 수행

//fib.c 
#include <unistd.h> 
pid_t root_pid 

int main() 
{ 
    root_pid = getpid(); 

    //... rest of your program 

} 

을 그리고 위에서 언급 한 바와 같이, doFib의 내부에 다음과 같은 당신의 if 성명을 발표 :이 코딩 문제를 탐구로

if (getpid() == root_pid) 
{ 
    //...print results 
} 
else 
{ 
    exit(result) 
} 
+0

최종 답은 시퀀스가 ​​아니라 인쇄가 필요합니다. 나는 내가 최종베이스 케이스 상태를위한 근원 부모인지를 발견 할 필요가 있을지도 모른다고 생각했다. 현재 pid가 루트/최상위 프로세스인지 감지하는 방법에 대한 몇 가지 코드 예제를 제공 할 수 있습니까? 나는 그것을 쓸데없이 봤다. – CODe

+0

좋아요, 일부 코드 예제로 업데이트했습니다 – Jason

+0

감사합니다.이 코드는 최종베이스 케이스에 대한 좋은 해결책입니다. 대단히 감사합니다. 이제는 누군가가 나머지를 알아낼 수 있기를 바랍니다. ;) – CODe