Go 生成数字时,代码进入无限循环

Go 生成数字时,代码进入无限循环,go,Go,我试图编写一些代码,生成七组七个唯一的、不重复的数字,范围从1到49。然而,当我运行代码时,它进入了一个无限循环,无限次地生成一个数字。只有在我的main()下包含了if else小循环时,才会出现这种情况,它的功能是检查重复的数字 重复检查背后的逻辑是否存在问题 package main import "fmt" import "math/rand" import "time" func main() { var j [7]int var n []int ran

我试图编写一些代码,生成七组七个唯一的、不重复的数字,范围从1到49。然而,当我运行代码时,它进入了一个无限循环,无限次地生成一个数字。只有在我的main()下包含了if else小循环时,才会出现这种情况,它的功能是检查重复的数字

重复检查背后的逻辑是否存在问题

package main

import "fmt"
import "math/rand"
import "time"

func main() {

    var j [7]int
    var n []int

    rand.Seed(time.Now().UTC().UnixNano())

    for m := 0; m < 7; m++ {
        for i := 0; i < 8; i++ {
            if i < 7 {
                var duplicate int = randInt(1, 49)
                n = append(n, duplicate)
                if i != 0 {
                    if !integerinarray(duplicate, n) {
                        j[i] = duplicate
                    } else {
                        i--
                    }
                } else {
                    j[i] = duplicate
                }
                fmt.Print(j[i], " ")
            } else {
                fmt.Println("\n")
                //fmt.Println(n)
            }
        }
    }

}

func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

func integerinarray(a int, s []int) bool {
    for _, b := range s {
        if b == a {
            return true
        }
    }
    return false
}
主程序包
输入“fmt”
导入“数学/兰德”
导入“时间”
func main(){
var j[7]int
变量n[]int
rand.Seed(time.Now().UTC().UnixNano())
对于m:=0;m<7;m++{
对于i:=0;i<8;i++{
如果我<7{
var duplicate int=randInt(1,49)
n=追加(n,重复)
如果我!=0{
if!整数数组(重复,n){
j[i]=重复
}否则{
我--
}
}否则{
j[i]=重复
}
格式打印(j[i],“”)
}否则{
fmt.Println(“\n”)
//fmt.Println(n)
}
}
}
}
func randInt(最小整数,最大整数)整数{
返回最小值+随机整数(最大-最小值)
}
func integerinarray(a int,s[]int)bool{
对于u,b:=范围s{
如果b==a{
返回真值
}
}
返回错误
}

首先,您需要格式化代码。 你的逻辑是不对的

改为

if integerinarray(duplicate, n) {

您需要调试代码。

首先,您需要格式化代码。 你的逻辑是不对的

改为

if integerinarray(duplicate, n) {

你需要调试你的代码。

我对你的程序做了一些修改,现在它做了你想做的事情


代码 random\u arr.go:

// distribute 1 ~ 49 to 7 group of arrays, each array contain 7 numbers,
// each element should appear one and only once,
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UTC().UnixNano())
}

func main() {
    var arr [7]int
    var used []int

    for i := 0; i < 7; i++ {
        for j := 0; j < 7; {
            for {
                x := randInt(1, 50)         // generate a random number,
                if !checkInSlice(x, used) { // new unique,
                    arr[j] = x
                    j++
                    used = append(used, x)
                    break
                }
            }
        }
        fmt.Printf("[%d] array: %v\n", i, arr)
    }

}

// generate random number in range [min, max),
func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

// check whether a number is in a slice,
func checkInSlice(a int, s []int) bool {
    for _, b := range s {
        if b == a {
            return true
        }
    }
    return false
}
[0] array: [19 24 47 9 26 21 25]
[1] array: [43 8 27 45 48 16 1]
[2] array: [22 42 31 15 28 39 40]
[3] array: [33 35 11 44 14 36 20]
[4] array: [17 10 7 4 12 6 5]
[5] array: [46 32 13 2 30 49 18]
[6] array: [3 37 34 29 41 38 23]

提示 关于更改:

// distribute 1 ~ 49 to 7 group of arrays, each array contain 7 numbers,
// each element should appear one and only once,
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UTC().UnixNano())
}

func main() {
    var arr [7]int
    var used []int

    for i := 0; i < 7; i++ {
        for j := 0; j < 7; {
            for {
                x := randInt(1, 50)         // generate a random number,
                if !checkInSlice(x, used) { // new unique,
                    arr[j] = x
                    j++
                    used = append(used, x)
                    break
                }
            }
        }
        fmt.Printf("[%d] array: %v\n", i, arr)
    }

}

// generate random number in range [min, max),
func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

// check whether a number is in a slice,
func checkInSlice(a int, s []int) bool {
    for _, b := range s {
        if b == a {
            return true
        }
    }
    return false
}
[0] array: [19 24 47 9 26 21 25]
[1] array: [43 8 27 45 48 16 1]
[2] array: [22 42 31 15 28 39 40]
[3] array: [33 35 11 44 14 36 20]
[4] array: [17 10 7 4 12 6 5]
[5] array: [46 32 13 2 30 49 18]
[6] array: [3 37 34 29 41 38 23]
  • 更改
    if/else
    的逻辑,使用另一个
    for
    循环来完成这个技巧(实际上更像是C或Java中的
    while()

    您的原始版本过于复杂,难以理解
  • 变量和函数的命名被更改为更易于阅读
  • 关于
    rand.Intn()
    ,如果希望数字范围为
    [0,49]
    ,则需要通过
    50,而不是
    49
  • fmt.Printf()
    中,您可以使用
    %v
    %v
    占位符轻松打印数组或切片
  • 将种子设定部件移动到
    init()
    ,该部件在
    main()
    之前自动调用(这是可选的)
可能的进一步改进:

// distribute 1 ~ 49 to 7 group of arrays, each array contain 7 numbers,
// each element should appear one and only once,
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UTC().UnixNano())
}

func main() {
    var arr [7]int
    var used []int

    for i := 0; i < 7; i++ {
        for j := 0; j < 7; {
            for {
                x := randInt(1, 50)         // generate a random number,
                if !checkInSlice(x, used) { // new unique,
                    arr[j] = x
                    j++
                    used = append(used, x)
                    break
                }
            }
        }
        fmt.Printf("[%d] array: %v\n", i, arr)
    }

}

// generate random number in range [min, max),
func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

// check whether a number is in a slice,
func checkInSlice(a int, s []int) bool {
    for _, b := range s {
        if b == a {
            return true
        }
    }
    return false
}
[0] array: [19 24 47 9 26 21 25]
[1] array: [43 8 27 45 48 16 1]
[2] array: [22 42 31 15 28 39 40]
[3] array: [33 35 11 44 14 36 20]
[4] array: [17 10 7 4 12 6 5]
[5] array: [46 32 13 2 30 49 18]
[6] array: [3 37 34 29 41 38 23]
  • 可以设计一个更好的算法,以便它对大范围的数字仍然有效,例如
    0~1000000

    当前的时间复杂度是O(n^2),我猜存在一个
    O(n)
    算法
  • 通过重构函数,使代码具有通用性和可重用性

我对您的程序做了一些修改,现在它可以满足您的要求


代码 random\u arr.go:

// distribute 1 ~ 49 to 7 group of arrays, each array contain 7 numbers,
// each element should appear one and only once,
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UTC().UnixNano())
}

func main() {
    var arr [7]int
    var used []int

    for i := 0; i < 7; i++ {
        for j := 0; j < 7; {
            for {
                x := randInt(1, 50)         // generate a random number,
                if !checkInSlice(x, used) { // new unique,
                    arr[j] = x
                    j++
                    used = append(used, x)
                    break
                }
            }
        }
        fmt.Printf("[%d] array: %v\n", i, arr)
    }

}

// generate random number in range [min, max),
func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

// check whether a number is in a slice,
func checkInSlice(a int, s []int) bool {
    for _, b := range s {
        if b == a {
            return true
        }
    }
    return false
}
[0] array: [19 24 47 9 26 21 25]
[1] array: [43 8 27 45 48 16 1]
[2] array: [22 42 31 15 28 39 40]
[3] array: [33 35 11 44 14 36 20]
[4] array: [17 10 7 4 12 6 5]
[5] array: [46 32 13 2 30 49 18]
[6] array: [3 37 34 29 41 38 23]

提示 关于更改:

// distribute 1 ~ 49 to 7 group of arrays, each array contain 7 numbers,
// each element should appear one and only once,
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UTC().UnixNano())
}

func main() {
    var arr [7]int
    var used []int

    for i := 0; i < 7; i++ {
        for j := 0; j < 7; {
            for {
                x := randInt(1, 50)         // generate a random number,
                if !checkInSlice(x, used) { // new unique,
                    arr[j] = x
                    j++
                    used = append(used, x)
                    break
                }
            }
        }
        fmt.Printf("[%d] array: %v\n", i, arr)
    }

}

// generate random number in range [min, max),
func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

// check whether a number is in a slice,
func checkInSlice(a int, s []int) bool {
    for _, b := range s {
        if b == a {
            return true
        }
    }
    return false
}
[0] array: [19 24 47 9 26 21 25]
[1] array: [43 8 27 45 48 16 1]
[2] array: [22 42 31 15 28 39 40]
[3] array: [33 35 11 44 14 36 20]
[4] array: [17 10 7 4 12 6 5]
[5] array: [46 32 13 2 30 49 18]
[6] array: [3 37 34 29 41 38 23]
  • 更改
    if/else
    的逻辑,使用另一个
    for
    循环来完成这个技巧(实际上更像是C或Java中的
    while()

    您的原始版本过于复杂,难以理解
  • 变量和函数的命名被更改为更易于阅读
  • 关于
    rand.Intn()
    ,如果希望数字范围为
    [0,49]
    ,则需要通过
    50,而不是
    49
  • fmt.Printf()
    中,您可以使用
    %v
    %v
    占位符轻松打印数组或切片
  • 将种子设定部件移动到
    init()
    ,该部件在
    main()
    之前自动调用(这是可选的)
可能的进一步改进:

// distribute 1 ~ 49 to 7 group of arrays, each array contain 7 numbers,
// each element should appear one and only once,
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UTC().UnixNano())
}

func main() {
    var arr [7]int
    var used []int

    for i := 0; i < 7; i++ {
        for j := 0; j < 7; {
            for {
                x := randInt(1, 50)         // generate a random number,
                if !checkInSlice(x, used) { // new unique,
                    arr[j] = x
                    j++
                    used = append(used, x)
                    break
                }
            }
        }
        fmt.Printf("[%d] array: %v\n", i, arr)
    }

}

// generate random number in range [min, max),
func randInt(min int, max int) int {
    return min + rand.Intn(max-min)
}

// check whether a number is in a slice,
func checkInSlice(a int, s []int) bool {
    for _, b := range s {
        if b == a {
            return true
        }
    }
    return false
}
[0] array: [19 24 47 9 26 21 25]
[1] array: [43 8 27 45 48 16 1]
[2] array: [22 42 31 15 28 39 40]
[3] array: [33 35 11 44 14 36 20]
[4] array: [17 10 7 4 12 6 5]
[5] array: [46 32 13 2 30 49 18]
[6] array: [3 37 34 29 41 38 23]
  • 可以设计一个更好的算法,以便它对大范围的数字仍然有效,例如
    0~1000000

    当前的时间复杂度是O(n^2),我猜存在一个
    O(n)
    算法
  • 通过重构函数,使代码具有通用性和可重用性

    • 我注意到一些事情

      • 将逻辑与“用于打印内容的逻辑”混合使用是个坏主意,请尝试将其分离(否则{fmt.Println(“\n”)})
      • 我不建议在for循环中更改迭代器值(I--)
      • 我会避免有太多的嵌套级别,制作一个generateSet函数
      • 使用片,可以使它们具有固定容量(var j[7]int)
      这里有更多的go最佳实践

      示例解决方案
      有几件事我注意到了

      • 将逻辑与“用于打印内容的逻辑”混合使用是个坏主意,请尝试将其分离(否则{fmt.Println(“\n”)})
      • 我不建议在for循环中更改迭代器值(I--)
      • 我会避免有太多的嵌套级别,制作一个generateSet函数
      • 使用片,可以使它们具有固定容量(var j[7]int)
      这里有更多的go最佳实践

      示例解决方案

      您不使用兰德软件包中的方法有什么原因吗?即:

      package main
      
      import (
          "math/rand"
          "time"
          "fmt"
      )
      
      func main() {
          rand.Seed(time.Now().UnixNano())
          randomInts := rand.Perm(49) 
          // you can also rand.Shuffle an existing set in version 1.10+
      
          var j [7][7]int
      
          for i, v := range randomInts {
              j[i/7][i%7] = v + 1
          }
          for i := 0; i < 7; i++ {
              fmt.Println(j[i])
          }
      }
      
      主程序包
      进口(
      “数学/兰德”
      “时间”
      “fmt”
      )
      func main(){
      rand.Seed(time.Now().UnixNano())
      随机点:=rand.Perm(49)
      //在1.10版中,您还可以对现有集进行rand.Shuffle+
      var j[7][7]int
      对于i,v:=范围随机点{
      j[i/7][i%7]=v+1
      }
      对于i:=0;i<7;i++{
      fmt.Println(j[i])
      }
      }
      
      您不使用兰德软件包中的方法有什么原因吗?即:

      package main
      
      import (
          "math/rand"
          "time"
          "fmt"
      )
      
      func main() {
          rand.Seed(time.Now().UnixNano())
          randomInts := rand.Perm(49) 
          // you can also rand.Shuffle an existing set in version 1.10+
      
          var j [7][7]int
      
          for i, v := range randomInts {
              j[i/7][i%7] = v + 1
          }
          for i := 0; i < 7; i++ {
              fmt.Println(j[i])
          }
      }
      
      主程序包
      进口(
      “数学/兰德”
      “时间”
      “fmt”
      )
      func main(){
      rand.Seed(time.Now().UnixNano())
      随机点:=rand.Pe