首页 > 解决方案 > 删除字符串切片中的相邻重复项

问题描述

我有一个问题陈述write an in-place function to eliminate the adjacent duplicates in a string slice.

我想出了以下代码

func main() {
    tempData := []string{"abc", "abc", "abc", "def", "def", "ghi"}
    removeAdjacentDuplicates(tempData)
    fmt.Println(tempData)
}

func removeAdjacentDuplicates(data []string) {
    for j := 1; j < len(data); {
        if data[j-1] == data[j] {
            data = append(data[:j], data[j+1:]...)
        } else {
            j++
        }
    }
    fmt.Println(data)
}

输出如下

[abc def ghi]
[abc def ghi ghi ghi ghi]

我的疑问是,如果在函数中修改了切片,那么在调用函数中,为什么切片没有给出正确的结果?此外,任何更好地理解slices(和底层array)的文章都会非常有帮助。

标签: arraysgoslice

解决方案


func removeAdjacentDuplicate 将切片“好像”它是对 tempData 的引用

main() 中 tempData 的容量和长度在程序的生命周期内保持不变

在 removeAdjacentDuplicate 函数中,每次发现一个重复项时,“ghi”的最终值都会从末尾移动到末尾 - 1。因此,在切片末尾的内存中,有重复的“ghi”

当控件返回主程序时,程序打印出现在修改的切片 tempData。因为它以类似的方式传递给对函数的引用,所以修改的是这个内存。函数调用没有复制内存

您可以通过在程序运行时查看 cap() 和 len() 来查看此行为

package main

import (
        "fmt"
)

func main() {
        tempData := []string{"abc", "abc", "abc", "def", "def", "ghi"}
        removeAdjacentDuplicates(tempData)
        fmt.Println(tempData,cap(tempData),len(tempData))
}

func removeAdjacentDuplicates(data []string) {
        for j := 1; j < len(data); {
                if data[j-1] == data[j] {
                        data = append(data[:j], data[j+1:]...)
        fmt.Println(data,cap(data),len(data))
                } else {
                        j++
                }
        }
        fmt.Println(data, cap(data),len(data))
}

推荐阅读