首页 > 解决方案 > 通道如何使用通道查找素数问题?

问题描述

我有一种使用 Go 解决查找素数问题的方法,如下所示:

package main

import (
    "fmt"
)

// Generate natural seri number: 2,3,4,...
func GenerateNatural() chan int {
    ch := make(chan int)
    go func() {
        for i := 2; ; i++ {
            ch <- i
        }
    }()
    return ch
}

// Filter: delete the number which is divisible by a prime number to find prime number
func PrimeFilter(in <-chan int, prime int) chan int {
    out := make(chan int)
    go func() {
        for {
            if i := <-in; i%prime != 0 {
                out <- i
            }
        }
    }()
    return out
}

func main() {
    ch := GenerateNatural()
    for i := 0; i < 100; i++ {
        prime := <-ch

        fmt.Printf("%v: %v\n", i+1, prime)
        ch = PrimeFilter(ch, prime)

    }
}

我不知道这种方法会发生什么:

默认情况下,通道是无缓冲的,这表明如果有相应的接收 (<- chan) 准备好接收发送的值,它们将只接受发送 (chan <-)

我无法想象上面的 Go 程序是如何运行的!

有人可以帮我看看前 10 个数字左右的上述 Go 程序的逐步流程吗?

标签: gochannel

解决方案


这是一个相当复杂的例子。在这两个函数中,go func(){...}()创建一个匿名 goroutine 并异步运行它,然后返回将从 goroutine 接收值的通道。PrimeFilter返回一个通道,该通道将接收不能被某个候选者整除的数字。

这个想法是prime := <-ch始终从通道中获取第一个元素。因此,要可视化流程:

  1. GenerateNatural()首先将数字 2、3、4... 发送到ch.

  2. 第一次循环迭代:

    一个。prime := <-ch读取第一个(质数)数字2

    湾。PrimeFilter(ch, 2)然后继续接收其余的数字(3, 4, 5, ...),并将不可被整除的数字发送2到输出通道。因此,返回的频道PrimeFilter(ch, 2)将接收数字(3, 5, 7, ...)。

    C。ch = PrimeFilter(ch, prime)在 main 函数中,现在将局部变量替换为上一步的输出。chPrimeFilter(ch, 2)

  3. 第二次循环迭代:

    一个。prime := <-ch从当前实例中读取第一个(素数)数ch(第一个数是3)。

    湾。PrimeFilter(ch, 3)然后继续接收(已经过滤的)数字,除了第一个数字(so, 5, 7, 9, ...),并将不可被整除的数字发送3到输出通道。因此,返回的频道PrimeFilter(ch, 2)将收到数字5, 7, 11, ...,因为可以被 .9整除3

    C。ch = PrimeFilter(ch, prime)在 main 函数中,现在将局部变量替换为上一步的输出。chPrimeFilter(ch, 3)

  4. ...


推荐阅读