使用 Go 语言统计 0-200000 的数字中,哪些是素数?

题目

使用 Go 语言统计 0-200000的数字中,哪些是素数?

思路

两种方法:

  1. 单循环遍历 1-200000 数字,并判断是否是素数。

  2. 使用了 Goroutine 和通道实现并发:

    • 通过创建两个通道 intChanprimeChan,以及一个 sync.WaitGroup 来协调 Goroutine 的执行。

    • 然后,启动三个 Goroutine:

      • InputIntChan:向 intChan 通道中写入整数数据。
      • PrimeCompute:从 intChan 通道中读取整数数据,并判断是否为素数,将素数写入 primeChan 通道。
      • readPrimeChan:从 primeChan 通道中读取素数数据并输出。

      最后,使用 sync.WaitGroup 等待所有 Goroutine 执行完毕。

代码实现

单循环实现

go 复制代码
package main

import (
	"fmt"
	"math"
	"time"
)

func main() {
	start := time.Now().Unix() // 记录开始时间
	primeChan := make(chan int, 2000000) // 创建一个缓冲大小为2000000的素数通道
	for i := 0; i <= 200000; i++ { // 判断从0到200000的整数是否为素数
		if isPrime(i) { // 如果是素数
			primeChan <- i // 写入素数通道
		}
	}
	end := time.Now().Unix() // 记录结束时间

	fmt.Println("总耗时时间:", end-start) // 输出总耗时时间
}

// 判断一个整数是否为素数
func isPrime(n int) bool {
	if n <= 1 {
		return false
	}

	for i := 2; i <= int(math.Sqrt(float64(n))); i++ { // 只需遍历到sqrt(n)即可,减少计算量
		if n%i == 0 {
			return false
		}
	}

	return true
}

Goroutine 和通道实现

好的,以下是给代码加上注释后的版本:

go 复制代码
package main

import (
	"fmt"
	"math"
	"strconv"
	"sync"
)

func main() {

	var wg sync.WaitGroup
	wg.Add(3)
	intChan := make(chan int, 1000)      // 创建一个缓冲大小为1000的整数型通道
	primeChan := make(chan int, 2000000) // 创建一个缓冲大小为2000000的整数型通道

	go InputIntChan(intChan, &wg) // 启动写入整数的协程

	go PrimeCompute(intChan, primeChan, &wg) // 启动计算素数并写入素数通道的协程

	go readIntChan(primeChan, &wg) // 启动读取素数并输出的协程

	wg.Wait() // 等待所有协程结束
}

// 判断一个整数是否为素数
func isPrime(n int) bool {
	if n <= 1 {
		return false
	}

	for i := 2; i <= int(math.Sqrt(float64(n))); i++ { // 只需遍历到sqrt(n)即可,减少计算量
		if n%i == 0 {
			return false
		}
	}

	return true
}

// 往通道中写入整数
func InputIntChan(intChan chan<- int, wg *sync.WaitGroup) {
	for i := 0; i <= 200000; i++ { // 写入200000个整数
		intChan <- i // 写入整数通道
		fmt.Println("写入Int通道==" + strconv.Itoa(i))
	}
	close(intChan) // 写入完成,关闭通道
	wg.Done()      // 协程结束,减少计数器
}

// 判断整数是否为素数,并往素数通道中写入素数
func PrimeCompute(intChan <-chan int, primeChan chan<- int, wg *sync.WaitGroup) {
	for i := range intChan { // 循环判断每个整数是否为素数
		if isPrime(i) {
			primeChan <- i // 如果是素数,往素数通道中写入素数
		}
	}
	close(primeChan) // 计算完毕,关闭素数通道
	wg.Done()        // 协程结束,减少计数器
}

// 从素数通道中读取素数并输出
func readIntChan(primeChan <-chan int, wg *sync.WaitGroup) {
	for i := range primeChan { // 循环读取素数通道中的素数
		fmt.Println("从通道中读取素数==" + strconv.Itoa(i))
	}
	wg.Done() // 协程结束,减少计数器
}

优化思路

创造多个协程处理写入读取通道

相关推荐
superxxd2 小时前
跨平台音频IO处理库libsoundio实践
开发语言·qt·音视频
海洲探索-Hydrovo2 小时前
TTP Aether X 天通透传模块丨国产自主可控大数据双向通讯定位模组
网络·人工智能·科技·算法·信息与通信
_OP_CHEN3 小时前
C++基础:(十二)list类的基础使用
开发语言·数据结构·c++·stl·list类·list核心接口·list底层原理
2401_841495645 小时前
【计算机视觉】基于复杂环境下的车牌识别
人工智能·python·算法·计算机视觉·去噪·车牌识别·字符识别
Jonkin-Ma6 小时前
每日算法(1)之单链表
算法
ONE_PUNCH_Ge6 小时前
Go 语言变量
开发语言
幼稚园的山代王6 小时前
go语言了解
开发语言·后端·golang
zhuyasen6 小时前
踩坑实录:Go 1.25.x 编译的 exe 在 Windows 提示“此应用无法运行”
windows·golang
晚风残6 小时前
【C++ Primer】第六章:函数
开发语言·c++·算法·c++ primer
杨云强6 小时前
离散积分,相同表达式数组和公式
算法