英文:
Remove all occurrences of the same element from slice
问题
我有以下代码:
func TestRemoveElement(t *testing.T) {
nums := []int{3, 2, 2, 3}
result := removeElement(nums, 3)
if result != 2 {
t.Errorf("期望值为 2,但实际值为 %d。", result)
}
}
func removeElement(nums []int, val int) int {
for i := 0; i < len(nums); i++ {
if nums[i] == val {
nums = append(nums[:i], nums[i+1:]...)
i-- // 删除元素后,需要将索引减1
}
}
return len(nums)
}
if
语句中的语句是根据这个答案中最常用的一种在切片中替换元素的方式。但是由于 i+1
,它无法删除最后一个元素。也就是说,如果在最后一个元素中找到匹配项,i+1
就会超出范围。有没有更好的方法来替换元素并考虑最后一个元素呢?
英文:
I have the following code:
func TestRemoveElement(t *testing.T) {
nums := []int{3, 2, 2, 3}
result := removeElement(nums, 3)
if result != 2 {
t.Errorf("Expected 2, but it was %d instead.", result)
}
}
func removeElement(nums []int, val int) int {
for i, v := range nums {
if v == val {
nums = append(nums[:i], nums[i+1:]...)
}
}
return len(nums)
}
The statement inside the if
statement is the most popular way of replacing an element in a slice per this answer. But this fails deleting the last element due to i+1
. i.e if a match is found in the last element, i+1
is out of bounds. What better way to replace elements that considers last elements?
答案1
得分: 2
看起来你想要移除所有等于val
的元素。一种方法是将不等于val
的值复制到切片的开头:
func removeElement(nums []int, val int) []int {
j := 0
for _, v := range nums {
if v != val {
nums[j] = v
j++
}
}
return nums[:j]
}
返回新的切片而不是返回长度会更方便调用者使用。
如果你只想移除第一个等于val
的元素,可以使用以下代码:
func removeElement(nums []int, val int) []int {
for i, v := range nums {
if v == val {
return append(nums[:i], nums[i+1:]...)
}
}
return nums
}
英文:
It looks like you are trying to remove all elements equal to val
. One way to do this is to copy values not equal to val
to the beginning of the slice:
func removeElement(nums []int, val int) []int {
j := 0
for _, v := range nums {
if v != val {
nums[j] = v
j++
}
}
return nums[:j]
}
Return the new slice instead of returning the length. It will be more convenient for the caller.
If you only want to remove the first element equal to val
, then use this code:
func removeElement(nums []int, val int) []int {
for i, v := range nums {
if v == val {
return append(nums[:i], nums[i+1:]...)
}
}
return nums
}
答案2
得分: 1
添加索引检查可以解决你的问题。Copy
比append
具有更好的性能,但你原来的append版本仍然可以工作。如果你正在使用切片,这是一个很好的页面,可以放入你的Go工具库中。另外请注意,下面的函数不会更新你传入的切片,所以虽然它会打印出删除了多少个项目,但原始切片不会删除这些项目。
func removeElement(nums []int, val int) int {
var i int
for {
if i == len(nums) {
break
}
if nums[i] == val {
nums = nums[:i+copy(nums[i:], nums[i+1:])]
i = 0
}
i++
}
return len(nums)
}
修改后的removeElement函数还返回修改后的列表。
func removeElement(nums []int, val int) (numberOfItemsRemoved int, newArr []int) {
var i int
for {
if i == len(nums) {
break
}
if nums[i] == val {
nums = nums[:i+copy(nums[i:], nums[i+1:])]
i = 0
}
i++
}
return len(nums), nums
}
你也可以通过引用修改原始切片,这样就不需要返回它了。
func removeElement(nums *[]int, val int) int {
var i int
for {
if i == len(*nums) {
break
}
slice := (*nums)
if slice[i] == val {
slice = slice[:i+copy(slice[i:], slice[i+1:])]
*nums = slice
i = 0
}
i++
}
return len(*nums)
}
示例用法:https://goplay.space/#leulqgwsjc
英文:
Adding an index check solves your issue. Copy
has better performance than append
but your original append version will still work. https://gist.github.com/xogeny/b819af6a0cf8ba1caaef
If you are working with slices this is a good page to have in your Go arsenal https://github.com/golang/go/wiki/SliceTricks
Also note that the function below doesn't update the slice you passed in, so while it will print how many items where removed, the original slice will not have those items removed.
func removeElement(nums []int, val int) int {
var i int
for {
if i == len(nums) {
break
}
if nums[i] == val {
nums = nums[:i+copy(nums[i:], nums[i+1:])]
i = 0
}
i++
}
return len(nums)
}
Modified removeElements that also returns the modded list
func removeElement(nums []int, val int) (numberOfItemsRemoved int, newArr []int) {
var i int
for {
if i == len(nums) {
break
}
if nums[i] == val {
nums = nums[:i+copy(nums[i:], nums[i+1:])]
i = 0
}
i++
}
return len(nums), nums
}
https://goplay.space/#1yfhTkZC4o
You can also modify the original slice by reference so that it doesn't have to be returned
func removeElement(nums *[]int, val int) int {
var i int
for {
if i == len(*nums) {
break
}
slice := (*nums)
if slice[i] == val {
slice = slice[:i+copy(slice[i:], slice[i+1:])]
*nums = slice
i = 0
}
i++
}
return len(*nums)
}
Example usage https://goplay.space/#leulqgwsjc
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论