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 過濾。逐步提取出素數。

 

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