【发布时间】:2020-01-16 16:44:07
【问题描述】:
我正在处理 go/golang,尝试编写带有字符串和种子的代码。它应该返回一个打乱的字符串,其中单词、标点符号和数字中的第一个和最后一个字母都没有改变。
例子:
我的名字是尼基。我的号码是 333
应该是
我的 nmae 是 Nkiki。我的 nebumr 是 333
我对 goland/go 很陌生。已经尝试使用rand.Shuffle 来做到这一点:
func splitText(text string) []string {
re := regexp.MustCompile("[A-Za-z0-9']+|[':;?().,!\\ ]")
return re.FindAllString(text, -1)}
func scramble(text string, seed int64) string {
rand.Seed(seed)
split := splitText(text)
for i := range split {
e := split[i]
r := []byte(e)
for i := 0; i < len(r); i++ {
l := len(r) - 1
if i == 0 {
return string(r[0])
}
if i == l {
return string(r[l])
}
if i > 0 || i < l {
n := rand.Intn(l)
x := r[i]
r[i] = r[n]
r[n] = x
}
if (r[i] >= 32 && r[i] <= 62) || (r[i] >= 91 && r[i] <= 96) {
return string(r[i])
}
}
}
return text
}
func main() {
v := ("The quick brown fox jumps over the lazy dog.")
scramble(v, 100)
fmt.Println(scramble(v, 100))
}
但这只会返回一个字母,并且只有在remoe f==0 或f==l 时,它才不会跳到下一个单词。
【问题讨论】:
-
在嵌套的 for 循环中,您有一个
if i==0条件,该条件在循环第一次运行时始终为真,因此它在不执行其余代码的情况下返回。内部 for 循环索引i遮蔽了外部循环i,所以这可能是您困惑的根源。 -
但是如何解决它才能打印和随机播放?
-
按照您的操作方式,您将失去单词边界和标点符号。所以我建议你改变你的算法。一种方法是将字符串转换为 []rune,然后迭代元素。在您进行迭代时,找出单词边界,使用 rand.Shuffle 将字节打乱,然后将生成的 []rune 转换为字符串并返回。
-
你能用一些代码示例解释一下吗?
-
我无法为您编写代码,但我描述的算法需要保留一个状态变量来告诉您是否在一个单词中。如果您看到一个字母 (unicode.IsLetter),您不在一个单词中,您将更改状态变量,并且只要您看到字母就继续。当你看到一个非字母时,这给了你单词的结尾。然后,您可以在 word start+1:word end-1 之间洗牌,然后继续。
标签: arrays go slice shuffle letter