golang:素数筛

《GO语言高级编程》设计中案例,仅作为笔记进行收藏。

package main

import (
	"context"
	"fmt"
)

// 返回生成自然数序列的管道:2,3,4……
func GenerateNatural(ctx context.Context) chan int {
	ch := make(chan int)

	go func() {
		for i := 2; ; i++ {
			// fmt.Printf("GenerateNatural:%v\n", i)
			select {
			case <-ctx.Done():
				return
			case ch <- i:
			}
		}
	}()

	return ch
}

// 管道过滤器:删除能被素数正常的数
func PrimeFileter(ctx context.Context, in <-chan int, prime int) chan int {
	out := make(chan int)
	go func() {
		for {
			// fmt.Printf("PrimeFileter-prime:%v\n", prime)
			if i := <-in; i%prime != 0 {
				// fmt.Printf("PrimeFileter-if:%v\n", i)
				select {
				case <-ctx.Done():
					return
				case out <- i:
				}
			}

			// fmt.Printf("PrimeFileter-for:%v\n", <-in)
		}
	}()
	return out
}

func main() {
	// 通过 Context 控制后台 Goroutine状态
	ctx, cancel := context.WithCancel(context.Background())

	// 自然数序列:2,3,4,……
	ch := GenerateNatural(ctx)

	for i := 0; i < 10; i++ {
		// 新出现的素数
		prime := <-ch
		fmt.Printf("%v:%v\n", i+1, prime)
		// 基于新素数构造的过滤器
		// 如果未产生新的素数,则通道 ch 为 nil;如果通道 ch 为 nil,则 GenerateNatural 生成新的自然数,发送给ch,则PrimeFileter 过滤,直到通道不为nil
		ch = PrimeFileter(ctx, ch, prime)
	}

	cancel()
}

GenerateNatural 函数内部启动⼀个Goroutine⽣产序列,返回对应的管道。

PrimeFilter 函数内部启动⼀个Goroutine将输入序列中是素数倍数的数提出,并返回新的序列,是⼀个新的
管道。

GenerateNatural 生产,PrimeFilter 过滤。逐步提取出素数。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章