相关信息
算法实现-golang实现交替打印数字字母
该题的关键在意通过channel进行控制
gopackage main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
numberChan := make(chan struct{})
letterChan := make(chan struct{})
wg.Add(2)
// 打印数字
go func() {
defer wg.Done()
for i := 1; i <= 26; i++ {
<-numberChan
fmt.Print(i)
letterChan <- struct{}{}
}
}()
// 打印字母
go func() {
defer wg.Done()
for i := 'A'; i <= 'Z'; i++ {
<-letterChan
fmt.Print(string(i))
if i != 'Z' {
numberChan <- struct{}{}
}
}
}()
// 启动
numberChan <- struct{}{}
wg.Wait()
}
输入为:[5,6,2,4,1,3] 输出: 561234
jspackage main
import (
"fmt"
"sync"
)
func main() {
nums := []int{1, 3, 5, 2}
var odds, evens []int
for _, n := range nums {
if n%2 != 0 {
odds = append(odds, n)
} else {
evens = append(evens, n)
}
}
oddTurn := make(chan struct{}, 1)
evenTurn := make(chan struct{}, 1)
done := make(chan struct{})
var once sync.Once
stop := func() {
once.Do(func() {
close(done)
})
}
var wg sync.WaitGroup
wg.Add(2)
oddTurn <- struct{}{}
go func() {
defer wg.Done()
defer stop()
for _, n := range odds {
select {
case <-done:
return
case <-oddTurn:
}
fmt.Print(n)
select {
case evenTurn <- struct{}{}:
case <-done:
return
}
}
}()
go func() {
defer wg.Done()
defer stop()
for _, n := range evens {
select {
case <-done:
return
case <-evenTurn:
}
fmt.Print(n)
select {
case oddTurn <- struct{}{}:
case <-done:
return
}
}
}()
wg.Wait()
fmt.Println()
}
jspackage main
import (
"fmt"
"sync"
)
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(2)
// 共同的打印逻辑
printFunc := func(name string, targetMod int) {
defer wg.Done()
for {
val, ok := <-ch
if !ok { // 如果通道关闭了,优雅退出
return
}
if val > 100 {
close(ch) // 超过 100,由当前协程负责关闭通道
return
}
// 校验是否轮到自己打印(奇数或偶数)
if val%2 == targetMod {
fmt.Printf("%s: %d\n", name, val)
ch <- val + 1 // 数字加 1,送回通道给另一个协程
} else {
// 如果拿到的数字不该自己打印,原封不动送回去(极少发生,由于无缓冲通道的特性)
ch <- val
}
}
}
go printFunc("协程 1 (奇数)", 1)
go printFunc("协程 2 (偶数)", 0)
ch <- 1 // 塞入初始值 1,启动交叉打印
wg.Wait()
}
本文作者:曹子昂
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!