【问题标题】:How to shuffle strings in arrays in golang?如何在golang中对数组中的字符串进行洗牌?
【发布时间】:2017-10-17 00:46:45
【问题描述】:

所以我创建了一个程序来帮助我决定玩哪个游戏。在我开始我的问题之前,让我向您展示我的代码:

package main

import (
    "fmt"
    "strconv"
    "time"
)

func main() {
    isArray := [10]string{"Paladins", "Overwatch", "CS:GO", "Tanki", "Left 4 Dead", "Rocket League", "Call Of Duty : AW", "Portal", "Star Citizen", "Star Wars : Battlefront"}
    fmt.Print("0,1,2,3,4,5,6,7,8,9 := ")

    var (
        va string
        ar string
    )

    fmt.Scanln(&va)
    i, _ := strconv.Atoi(va)

    fmt.Print("You Should Play : ")
    fmt.Print(isArray[i], "\n")
    fmt.Print("[Y/N] := ")
    fmt.Scanln(&ar)

    if ar != "N" || ar != "n" {
        fmt.Print("OK")
    }

    time.Sleep(3 * time.Second)
}

所以当我已经知道哪个号码会触发游戏时,问题就开始了,如果我使用它两次。所以我试图让字符串随机化,比如每次使用时都洗牌,我该怎么做?

【问题讨论】:

标签: arrays string go random


【解决方案1】:
 package main

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

 func shuffle(src []string) []string {
         final := make([]string, len(src))
         rand.Seed(time.Now().UTC().UnixNano())
         perm := rand.Perm(len(src))

         for i, v := range perm {
                 final[v] = src[i]
         }
         return final
 }

【讨论】:

  • 花絮,UnixNano 返回一个 UTC 时间值,因此实际上不需要在种子中使用 .UTC()
【解决方案2】:

好吧,就您的问题而言,为什么不使用rand.Intn() 选择一个随机数并打印游戏而不是让用户选择一个数字?

isArray := [10]string{"Paladins", "Overwatch", "CS:GO", "Tanki", "Left 4 Dead", "Rocket League", "Call Of Duty : AW", "Portal", "Star Citizen", "Star Wars : Battlefront"}
n := rand.Intn(9)
fmt.Printf("You Should Play : %s\n", isArray[n])

但是如果你想为了它而对数组中的字符串进行洗牌,那么你可以这样做:

// Shuffle array in place
l := len(isArray)-1
for i := 0; i <=l; i++ {
    n := rand.Intn(l)
    // swap
    x := isArray[i]
    isArray[i] = isArray[n]
    isArray[n] = x
}

这应该是 O(n),虽然我不确定 Intn 的复杂性。如果你真的想变得花哨,你可以:

  1. 创建第二个 touples 数组 (randomArray),其中包含 isArray 中的随机数和元素位置。
  2. 按随机数排序此数组
  3. 创建一个新数组,复制isArray的元素,但按我们的randomArray排序

【讨论】:

  • 我考虑过使用您的第一个示例,但它不起作用。每次我运行代码时,它总是说 Left 4 Dead。 PS(我将 rand.Intn(10) 的值更改为 rand.Intn(9),因为数组从 0 开始。
  • 您在rand.Intn() 之前是否调用过rand.Seed(time.Now().UTC().UnixNano()) 之类的东西?否则它将始终生成相同的数字:5
  • 哇哇哇哇哇;我刚刚添加了它,它可以工作:-),谢谢男人
  • 你能解释一下为什么必须在 rand.Intn() 之前添加它
  • rand 是一个随机数生成器 - 给定一个起始数字,算法将生成其他随机数字(很难猜到下一个数字)。因为它是一种算法,如果您从相同的数字(种子)开始,下一个将始终相同。所以第一次使用前需要播种
【解决方案3】:
package main

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

type list []string

func main() {

    s := list{
        "Tanki",
        "Left 4 Dead",
        "Rocket League",
        "Call Of Duty : AW",
    }
    s.shuffle()
    s.print()
}

func (l list) print() {
    for i, v := range l {
        fmt.Println(i, v)
    }
}

func (l list) shuffle() list {
    src := rand.NewSource(time.Now().UnixNano())
    r := rand.New(src)
    for i := range l {
        n := r.Intn(len(l) - 1)
        l[i], l[n] = l[n], l[i]
    }
    return l
}

【讨论】:

  • 欢迎来到stackoverflow。请充分解释你的答案。仅仅发布代码并不能帮助其他用户理解您的答案。
猜你喜欢
  • 1970-01-01
  • 2016-06-19
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
相关资源
最近更新 更多