
本文介绍如何正确比较两个字符串切片,提取它们的共同元素(交集),避免原地修改导致的索引越界和逻辑错误,并提供高效、安全的实现方案。
本文介绍如何正确比较两个字符串切片,提取它们的共同元素(交集),避免原地修改导致的索引越界和逻辑错误,并提供高效、安全的实现方案。
在 Go 中,若想“删除两个切片中的唯一值”,实际需求通常是保留同时存在于两个切片中的元素(即交集),而非字面意义的“去重”。原始代码存在多个关键问题:
- 在遍历 names 的同时原地修改该切片(append(names[:i], names[i+1:]...)),导致索引错位与 panic: runtime error: index out of range;
- 内层循环条件 k < len(board)-1 错误地跳过 board 最后一个元素;
- if names[i] != board[k] 后直接删除,逻辑颠倒——应仅在找到匹配项时才保留,而非不匹配就删。
✅ 正确思路是:遍历 names,对每个元素检查是否存在于 board 中;若存在,则加入结果切片。
以下是推荐实现(时间复杂度 O(m×n),适用于中小规模数据):
package main
import "fmt"
func main() {
names := []string{"F5", "F7", "C6", "H5", "G5"}
board := []string{"B4", "D4", "G5", "F5", "F7", "C6"}
var intersection []string
for _, n := range names {
for _, b := range board {
if n == b {
intersection = append(intersection, n)
break // 找到即跳出内层循环,避免重复添加相同元素
}
}
}
fmt.Printf("交集元素: %v\n", intersection) // 输出: [F5 F7 C6 G5]
}⚠️ 注意事项:
- 使用 range 替代手动索引,代码更简洁、不易出错;
- break 至关重要:防止同一元素在 board 中多次出现时被重复添加;
- 若需去重后的交集(如 names 或 board 自身含重复项),应配合 map[string]bool 去重预处理;
- 对于大规模数据(如切片长度 > 10⁴),建议先将 board 转为 map 实现 O(1) 查找,将整体复杂度优化至 O(m+n):
boardSet := make(map[string]bool)
for _, b := range board {
boardSet[b] = true
}
for _, n := range names {
if boardSet[n] {
intersection = append(intersection, n)
}
}总结:切片操作不可边遍历边修改;求交集应以“查找存在性”为核心逻辑,优先保证正确性,再根据性能需求选择基础双循环或哈希映射优化方案。


















