首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用golang和并发验证9x9 sudoku板

使用golang和并发验证9x9 sudoku板
EN

Stack Overflow用户
提问于 2019-10-24 01:51:36
回答 1查看 497关注 0票数 1

我通过在LeetCode上做编码问题来练习歌朗。我试图解决一个简单的sudoku难题(它只是验证董事会)。没有具有相同数字的行,没有具有相同数字的列,也没有具有相同数字的3x3块。我试图使用并发性来学习Go例程/频道/等等.

我不能让服务队最后确定

代码语言:javascript
运行
复制
import (
    "sync"
    "fmt"
)
func isValidSlice(slice []byte, results chan<- bool, wg *sync.WaitGroup) {
    fmt.Println(slice)
    seen := make(map[byte]bool)
    for _,val := range(slice) {
        if seen[val] {
            if val != '.'{
                results <- false
                defer wg.Done()
                return    
            }
        } else {
            seen[val] = true
        }
    }

    results <- true
    defer wg.Done()
}

func isValidSudoku(board [][]byte) bool {
    // Channel to receive solution
    c := make(chan bool)

    // Number of routines that will run (9 for rows, 9 for cols, 9 for 3x3 blocks)
    var wg sync.WaitGroup

    // Check every row
    for x:= 0; x < 9; x++{
        wg.Add(1)
        go isValidSlice(append([]byte{}, board[x]...), c, &wg)
    }
    for y:= 0; y < 9; y++{
        wg.Add(1)
        go isValidSlice(append([]byte{}, board[0:9][y]...), c, &wg)   
    }
    // Check every 3x3 block
    for x:= 0; x <= 6; x += 3{
        for y := 0; y <= 6; y += 3{
            block_digits := append([]byte{}, board[x][y:y+3]...)
            block_digits = append(block_digits, board[x+1][y:y+3]...)
            block_digits = append(block_digits, board[x+2][y:y+3]...)
            wg.Add(1)
            go isValidSlice(block_digits, c, &wg)
        }
    }

    fmt.Println("got here")
    wg.Wait()
    fmt.Println("never got here")

    for result := range c{
        if !result{
            return false
        }
    }

    return true
}

我期待着wg.Wait()锁的发布和代码的前进。然后,我期望通道中的结果之一是false,如果是的话,返回false。否则,在通道中的所有元素都被遍历并且没有发现false之后,我希望得到一个True。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-24 02:44:55

您的goroutines不能调用wg.Done(),因为它们都等待在通道中添加它们的值。但是,由于您只在wg.Wait()之后使用来自通道的值,所以所有的goroutines都不能调用wg.Done()

您实际上不需要一个WaitGroup,只需删除它。

其他评论:

  1. 您应该将defer wg.Done()移到isValidSlice的第一行。调用函数的最后一行没有多大意义。
  2. 您只需要一个WaitGroup,如果您想正确关闭通道,您可以在一个额外的goroutine中这样做,有关如何实现的示例,请参阅下面的示例。

代码语言:javascript
运行
复制
func isValidSudoku(board [][]byte) bool {

    // ...

    fmt.Println("got here")
    go func(){
        wg.Wait()
        close(c)
    }()
    fmt.Println("never got here")

    for result := range c{
        if !result{
            go func(){
                for _ := range c {
                }
            }()        
            return false
        }
    }
    return true
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58533062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档