删除字符串切片中的相邻重复项
Remove Adjacent Duplicates in string slice
我有问题要 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]
我的疑问是,如果在函数中修改了 slice,那么在调用函数中,为什么 slice 没有给出正确的结果?
此外,任何能更好地理解 slices
(和底层 array
)的文章都会非常有帮助。
在您的代码中,removeAdjacentDuplicates
想要改变参数中传递的 slcie。这真的不可能。
这个函数应该 return 新切片,就像 append
一样。
func removeAdjacentDuplicates(data []string) []string{
for j := 1; j < len(data); {
if data[j-1] == data[j] {
data = append(data[:j], data[j+1:]...)
} else {
j++
}
}
return data
}
如果你真的想改变参数,这是可能的,但你需要传递一个指向切片的指针*[]string
函数 removeAdjacentDuplicate 获取切片“就好像”它是对 tempData 的引用
main()中tempData的容量和长度在整个生命周期内保持不变
节目
在 removeAdjacentDuplicate 函数中,每次找到一个 dupe 时,“ghi”的最终值从末尾移动到末尾 - 1。因此在
切片有重复的“ghi”
当控制returns到main时,程序打印出now modified
切片临时数据。因为它以类似的方式传递给对
功能是修改了这段内存。函数调用没有复制内存
您可以在程序运行时通过查看 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))
}
试试这个功能:
func deleteAdjacentDuplicate(slice []string) []string {
for i := 1; i < len(slice); i++ {
if slice[i-1] == slice[i] {
copy(slice[i:], slice[i+1:]) //copy [4] where there is [3, 4] => [4, 4]
slice = slice[:len(slice)-1] //removes last element
i-- //avoid advancing counter
}
}
return slice
}
我有问题要 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]
我的疑问是,如果在函数中修改了 slice,那么在调用函数中,为什么 slice 没有给出正确的结果?
此外,任何能更好地理解 slices
(和底层 array
)的文章都会非常有帮助。
在您的代码中,removeAdjacentDuplicates
想要改变参数中传递的 slcie。这真的不可能。
这个函数应该 return 新切片,就像 append
一样。
func removeAdjacentDuplicates(data []string) []string{
for j := 1; j < len(data); {
if data[j-1] == data[j] {
data = append(data[:j], data[j+1:]...)
} else {
j++
}
}
return data
}
如果你真的想改变参数,这是可能的,但你需要传递一个指向切片的指针*[]string
函数 removeAdjacentDuplicate 获取切片“就好像”它是对 tempData 的引用
main()中tempData的容量和长度在整个生命周期内保持不变 节目
在 removeAdjacentDuplicate 函数中,每次找到一个 dupe 时,“ghi”的最终值从末尾移动到末尾 - 1。因此在 切片有重复的“ghi”
当控制returns到main时,程序打印出now modified 切片临时数据。因为它以类似的方式传递给对 功能是修改了这段内存。函数调用没有复制内存
您可以在程序运行时通过查看 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))
}
试试这个功能:
func deleteAdjacentDuplicate(slice []string) []string {
for i := 1; i < len(slice); i++ {
if slice[i-1] == slice[i] {
copy(slice[i:], slice[i+1:]) //copy [4] where there is [3, 4] => [4, 4]
slice = slice[:len(slice)-1] //removes last element
i-- //avoid advancing counter
}
}
return slice
}