QQ水群时看到这么一个段子,虽然段子很老套,但这么工整一段话段话看起来就让人手痒,就做一个代码练习吧。

image1.png

写一个能随机生成这段话的代码。但是如果只是一模一样的生成就有点太无聊了,最好是能根据输入的词能够按这样的模板输出。

也就是将 “喝xx杯奶茶”提取出来,然后根据提取词随机生成。

提取数字与汉字

把数字与汉字分别提取出来,存储在一个[]string切片中 也就是[][]string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
func preParam() [][]string {
var s = "喝100杯奶茶\n来99个拥抱\n看98场日落\n要97次接吻\n拍96张照片\n买95朵玫瑰\n去94家餐馆\n看93次大海\n走92条小巷\n打91次雨伞\n要90场牵手\n种89个草莓\n盖88次被子\n递87杯温水\n热86次剩饭\n看85次电影\n做84顿午饭\n切83个水果\n吃82次甜品\n喝81次暖茶\n要80次拥抱\n吃79遍烧烤\n烤78次肉串\n涮77次火锅\n来76次海鲜\n吃75种小吃\n参74场晚宴\n喝73杯喜酒\n吃72次西餐\n尝71颗糖果\n给你70枚吻\n荡69遍秋千\n看68次日出\n躺67次草地\n看66次星空\n闻65次头发\n抱64次肩膀\n吻63次脸颊\n亲62次锁骨\n咬61次耳朵\n有60次相拥\n看59场鬼片\n去58个城市\n吃57桶米花\n逛56个商厦\n打55次的士\n坐54次公交\n等53次地铁\n开52次自驾\n站51遍路灯\n睡50次怀里\n去49个鬼屋\n看48场表演\n逗47只动物\n坐46次飞车\n玩45次激流\n滑44次滑梯\n坐43次飞椅\n转42次陀螺\n吊41次吊索\n吃40次小吃\n捂39次肚子\n揉38次肩膀\n捶37次后背\n捏36次小腿\n暖35次脚丫\n摸34次脑袋\n撮33次肋骨\n挠32次手心\n逗31场大笑\n要30次拥吻\n放29个气球\n钓28只大鱼\n玩27次飞镖\n放26次风筝\n冲25次瀑布\n滑24艘小船\n蹦23场蹦极\n跳22次跳伞\n漂21次河流\n生20次闷气\n骑19次单车\n看18场大雪\n玩17遍飞艇\n去16次森林\n探15个峡谷\n踏14个小溪\n爬13座高山\n看12个沙漠\n坐11次轮船\n写10封情书\n唱9首情歌\n堆8个雪人\n摘7朵野花\n看6场流星\n许5个愿望\n醉4次夜酒\n种3棵玫瑰\n吵2次架\n爱1辈子"
m := extractKeyValuePairs(s)
return m
}

func extractKeyValuePairs(sentence string) [][]string {
resultMap := make([][]string, 100)
//将句子拆分为行
lines := strings.Split(sentence, "\n")
for _, line := range lines {
splitWord(line, &resultMap)
}
return resultMap
}

func splitWord(input string, m *[][]string) [][]string {
var result []string
var currentWord string
var intWord string
var key int
for _, char := range input {
if unicode.Is(unicode.Han, char) {
// 遇到汉字,先保存当前词
if intWord != "" {
key, _ = strconv.Atoi(intWord)
}
// 如果是汉字,添加到当前词中
currentWord += string(char)
} else if unicode.IsDigit(char) {
// 遇到数字,先保存当前词
if currentWord != "" {
result = append(result, currentWord)
currentWord = ""
}
// 将数字作为单独的词添加
if !unicode.IsSpace(char) {
intWord += string(char)
}
}
}
// 添加最后一个词(如果有的话)
if currentWord != "" {
result = append(result, currentWord)
}
(*m)[key-1] = result

return *m
}

拿到分好词的切片就可以直接打印出来了。这里因为用提取的数字作为key,所以就把切片倒序打印。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func ForLove() {
var s = "喝100杯奶茶\n来99个拥抱\n看98场日落\n要97次接吻\n拍96张照片\n买95朵玫瑰\n去94家餐馆\n看93次大海\n走92条小巷\n打91次雨伞\n要90场牵手\n种89个草莓\n盖88次被子\n递87杯温水\n热86次剩饭\n看85次电影\n做84顿午饭\n切83个水果\n吃82次甜品\n喝81次暖茶\n要80次拥抱\n吃79遍烧烤\n烤78次肉串\n涮77次火锅\n来76次海鲜\n吃75种小吃\n参74场晚宴\n喝73杯喜酒\n吃72次西餐\n尝71颗糖果\n给你70枚吻\n荡69遍秋千\n看68次日出\n躺67次草地\n看66次星空\n闻65次头发\n抱64次肩膀\n吻63次脸颊\n亲62次锁骨\n咬61次耳朵\n有60次相拥\n看59场鬼片\n去58个城市\n吃57桶米花\n逛56个商厦\n打55次的士\n坐54次公交\n等53次地铁\n开52次自驾\n站51遍路灯\n睡50次怀里\n去49个鬼屋\n看48场表演\n逗47只动物\n坐46次飞车\n玩45次激流\n滑44次滑梯\n坐43次飞椅\n转42次陀螺\n吊41次吊索\n吃40次小吃\n捂39次肚子\n揉38次肩膀\n捶37次后背\n捏36次小腿\n暖35次脚丫\n摸34次脑袋\n撮33次肋骨\n挠32次手心\n逗31场大笑\n要30次拥吻\n放29个气球\n钓28只大鱼\n玩27次飞镖\n放26次风筝\n冲25次瀑布\n滑24艘小船\n蹦23场蹦极\n跳22次跳伞\n漂21次河流\n生20次闷气\n骑19次单车\n看18场大雪\n玩17遍飞艇\n去16次森林\n探15个峡谷\n踏14个小溪\n爬13座高山\n看12个沙漠\n坐11次轮船\n写10封情书\n唱9首情歌\n堆8个雪人\n摘7朵野花\n看6场流星\n许5个愿望\n醉4次夜酒\n种3棵玫瑰\n吵2次架\n爱1辈子"
param := preParam(s)
summary(param)
}
func summary(m [][]string) {
fmt.Println("======================================================")
var s string
for i := len(m) - 1; i > -1; i-- {
s += m[i][0]
s += strconv.Itoa(i + 1)
s += m[i][1]
s += "\n"
}
fmt.Println(s)
fmt.Println("======================================================")
}

//======================================================
//喝100杯奶茶
//来99个拥抱
//看98场日落
//要97次接吻
//拍96张照片
//......

随机排序与切片分段

现在要实现随机排序生成,但是需要注意最后这几个不太适合随机排序不然就成爱2辈子了(

所以把这么多条做一个切片分段,每十条分一段。有一个类似的算法题用作练习。

LeetCode.915

1
2
3
4
5
6
7
8
9
10
11
12
func splitSlice(slice [][]string, size int) [][][]string {
var result [][][]string
// 遍历切片并分割
for i := 0; i < len(slice); i += size {
end := i + size
if end > len(slice) {
end = len(slice) // 确保不超出范围
}
result = append(result, slice[i:end])
}
return result
}

image2.png

然后在每个 小分段中做随机排序。同样有一题简单的算法题。

LeetCode.384

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
func randomMod(m [][]string) {
fmt.Println("======================================================")
sp := splitSlice(m, 10)
rand.New(rand.NewSource(time.Now().UnixNano()))
for z := len(sp) - 1; z > 0; z-- {
rand.Shuffle(len(sp[z]), func(i, j int) {
sp[z][i], sp[z][j] = sp[z][j], sp[z][i]
})
}
//因为切片分段数据结构改变了,重新写个打印方法
var c = 100
var resultSlice []string
for i := len(sp) - 1; i > -1; i-- {
for j := len(sp[i]) - 1; j > -1; j-- {
var s string
s += sp[i][j][0]
s += strconv.Itoa(c)
c--
s += sp[i][j][1]
resultSlice = append(resultSlice, s)
}
}
strings.Join(resultSlice, "\n")

for i := range resultSlice {
fmt.Println(resultSlice[i])
}
fmt.Println("======================================================")
}
//======================================================
//打100次雨伞
//要99次接吻
//看98次大海
//来97个拥抱
//看96场日落
//.....