2017-11-22 4 views
1

私はgolangでn個のgoroutinesを使ってチャネル経由で通信するフィボナッチ再帰を実装しようとしています。はn個のゴルーチンと通信します

私は関数から整数を返していますが、実際にはf(n-1)+ f(n-2)の合計をチャネルCで送信していますが、これは正しく動作しません。それは正しい最初の2つの値を印刷し、すべての値が後ちょうど1

package main 

import "fmt" 

// Fibonacci in a recursive version 
func fiboR(n int, c chan int) int { 

    if(n == 0){ 
     c <- 0 
     return 0 
    } else if n == 1 { 
     c <- 1 
     return 1 
    } else{ 
     c <- fiboR(n-1,c) + fiboR(n-2,c) 
     return fiboR(n-1,c) + fiboR(n-2,c) 
    } 

} 


func main() { 
    for i := 0; i < 10; i++ { 
    procchan := make(chan int) 
    go fiboR(i,procchan) 
    fmt.Println(i,<-procchan) 
} 
} 

である。また、それは、二つの再帰呼び出しを受信するためのチャネルを使用することは可能でしょうか?

答えて

2

解決策は、iの値を増やすと、チャネルから抽出した1つの値より多くを出力しようとします。 何あなたのコードがために、チャネルに送信しようとする各I:

0: 0 
1: 1 
2: 1,0,1 
3: 1,0,1,1,2 
4: 1,0,1,1,2,1,0,1,3 
... 

あなたは、各iについての新しいチャネルを作成し、一つの値だけを抽出しているので、いつでも上記の行の最初の値を取得します。

これらの変更を加えて実行しようとすると、望むもの(https://play.golang.org/p/_mn3l5x8iZ)が出力されます。 @nisseforsに追加

package main 

import "fmt" 

// Fibonacci in a recursive version 
func fiboRchan(n int, c chan int) { 
    c <- fiboR(n) 
} 

func fiboR(n int) int { 

    if n == 0 { 
     return 0 
    } else if n == 1 { 
     return 1 
    } else { 
     return fiboR(n-1) + fiboR(n-2) 
    } 

} 

func main() { 

    for i := 0; i < 10; i++ { 
     procchan := make(chan int) 
     go fiboRchan(i, procchan) 
     fmt.Println(i, <-procchan) 
    } 

} 
+0

'<-procchan'にアクセスしている場合は、値を持ってから続行するまでチャンネルを待っていません。そうすればforループはシーケンシャル実行と同じですね。 –

+0

はいこれは順次と同じです。 1つのゴルーチンを起動し、最初の結果を待って結果を表示し、別の結果を表示します。問題はあなたのgoroutinesが各回帰のチャンネルで値を返すことです。f(2)を呼び出す前にf(2)を呼び出すと、f(1)とfその前にチャンネルに値を入力します。そして、あなたが問題を引き起こす最初の価値を握っているだけなので。 – nissefors

+0

@NanduKalidindi申し訳ありませんが、私は明確にユーザー名を確認せず、あなたが3rdeye7のように応答しました – nissefors

1

は、シーケンシャル1が原因であなたが戻って、その後、次の繰り返しに進み、チャネル上で待機していることになるループの中で最も可能性がある主なプロセスに答えます。 https://play.golang.org/p/7e3JnWeSp6

package main 

import "fmt" 

// Fibonacci in a recursive version 
func fiboRchan(n int, c chan int) { 
     fmt.Println("PROCESSING FOR %d", n) 
    c <- fiboR(n) 
} 

func fiboR(n int) int { 
    if n == 0 { 
     return 0 
    } else if n == 1 { 
     return 1 
    } else { 
     return fiboR(n-1) + fiboR(n-2) 
    } 

} 

func main() { 
    var arr[10]chan int 
    for i := 0; i < 10; i++ { 
     procchan := make(chan int) 
     arr[i] = procchan 
     go fiboRchan(i, procchan) 
    } 
    // By now all the go routines are fired 

    // Now iterate through the channel array and read from the 
    // respective channel 
    for i:=0; i< 10; i++ { 
     fmt.Println(i, <-arr[i]) 
    } 

} 

ループのために別々に一度、その後、それぞれに対応しているチャンネルをすべてfibonaccisを発射でき、main関数内のマイナーな変更は、ルーチンは

遊び場のURLにアクセスすることができます行きます

関連する問題