任务是一个Golang 的面试题:找出从一到N之间的所有素数。
可以一个一个的找:
// find out all the primes from 1 to N
package main
import (
"fmt"
"math"
"sync"
)
func main() {
var n int
fmt.Scan(&n)
primes := findPrimes(n)
fmt.Println(primes)
}
func findPrimes(n int) []int {
primes := make([]int, 0)
for i := 2; i <= n; i++ {
isPrime := true
for j := 2; j <= int(math.Sqrt(float64(i))); j++ {
if i%j == 0 {
isPrime = false
break
}
}
if isPrime {
primes = append(primes, i)
}
}
return primes
}
并行的方式
这个方式在多核上的效率更高。
// find out all the primes from 1 to N
package main
import (
"fmt"
"math"
"sync"
)
func main() {
var n int
fmt.Scan(&n)
primes := findPrimes2(n)
fmt.Println(primes)
}
// use channel to parallel the process
func findPrimes2(n int) []int {
primes := make([]int, 0)
res := make(chan int, 10) // channel to receive the prime number
go primeWorker(n, res)
for prime := range res {
primes = append(primes, prime)
}
return primes
}
func primeWorker(n int, res chan int) {
// use a buffered channel to run the goroutine in parallel
ch := make(chan int, 10)
go func() {
for i := 2; i <= n; i++ {
// send the prime number to channel
ch <- i
}
close(ch) // close the channel
}()
// get the prime number from channel and start a goroutine to check if it is prime
var wg sync.WaitGroup
for i := range ch {
wg.Add(1)
go func(i int) {
fmt.Println("checking", i, "is prime or not")
defer wg.Done()
if isPrime(i) {
res <- i // send the prime number to channel
}
}(i)
}
go func() {
wg.Wait()
close(res)
}()
}
func isPrime(n int) bool {
isPrime := true
for j := 2; j <= int(math.Sqrt(float64(n))); j++ {
if n%j == 0 {
isPrime = false
break
}
}
return isPrime
}