子数组元素分配至其他子数组:程序偶发索引越界问题求优化
问题分析与优化方案
为什么会随机出现索引越界?
你的代码里有两个关键问题导致了随机的索引越界错误:
- Go中map的遍历顺序是随机的:你用
map[int][]string存储数组列表,遍历thisMap时,k>0的键(也就是A2、A3)的遍历顺序不确定。比如某次先处理k=2,处理后thisMap[0](A1)长度会缩短;如果下一次先处理k=1再处理k=2,thisMap[0]的长度可能已经小于k,此时访问thisMap[0][k]就会触发索引越界。 - 索引依赖键值的逻辑不合理:你直接用
k作为A1的索引,但A1的长度在不断缩短,当A1长度小于k时,必然会越界。
优化后的实现方案
我们改用slice存储数组列表(保证顺序固定),重新设计分配逻辑:先取出A1的所有元素,先给每个空数组分配至少一个元素,剩余元素再按顺序循环追加到各个数组中,确保没有空数组。
下面是优化后的代码:
package main import "fmt" func main() { // 用slice存储数组列表,顺序固定:A1在索引0,后面是需要填充的空数组 arrayList := [][]string{ {"first", "second", "third", "fourth", "fifth"}, // A1:初始元素 {}, // A2:空数组 {}, // A3:空数组 {}, // A4:空数组 } // 提取A1的所有元素 source := arrayList[0] // 计算需要填充的目标数组数量 targetCount := len(arrayList) - 1 // 第一步:给每个空数组先分配至少一个元素 for i := 1; i <= targetCount; i++ { if len(source) == 0 { break // 没有元素可分配了 } // 取出source的第一个元素,分配给当前目标数组 arrayList[i] = append(arrayList[i], source[0]) // 从source中移除已分配的元素 source = source[1:] } // 第二步:把剩余的元素按顺序分配给各个目标数组(循环追加) idx := 1 for _, val := range source { arrayList[idx] = append(arrayList[idx], val) idx = (idx % targetCount) + 1 // 循环切换目标数组 } // 清空A1(如果不需要保留原A1的话,可根据需求调整) arrayList[0] = nil // 打印结果 for i, arr := range arrayList { fmt.Printf("A%d -> %v\n", i+1, arr) } }
优化点说明
- 用slice保证顺序:避免了map遍历顺序随机的问题,能按固定顺序处理A2、A3、A4。
- 分阶段分配元素:先确保每个空数组至少有一个元素,再把剩余元素循环分配,完全符合你示例中的逻辑。
- 高效的元素转移:通过切片操作直接移动元素,避免了不必要的循环和判断,性能更优。
- 彻底避免索引越界:每次分配前检查source的长度,循环分配时通过取模保证索引不会超出目标数组范围。
运行结果示例
A1 -> <nil> A2 -> [first fifth] A3 -> [second] A4 -> [third fourth]
(如果需要保留A1的元素,可去掉arrayList[0] = nil这一行)
内容的提问来源于stack exchange,提问作者octain
相关产品推荐
相关产品推荐

