Golang:传入切片作为参考问题
Posted
技术标签:
【中文标题】Golang:传入切片作为参考问题【英文标题】:Golang: Passing in Slice as Reference issue 【发布时间】:2014-10-09 19:16:04 【问题描述】:我正在尝试编写一个计算数组中反转的程序,但由于引用问题,我的数组没有正确排序,因此即使我认为切片是通过 Golang 中的引用传递的,我的计数也会混乱。
这是我的代码:
package main
import (
"fmt"
)
func InversionCount(a []int) int
if len(a) <= 1
return 0
mid := len(a) / 2
left := a[:mid]
right := a[mid:]
leftCount := InversionCount(left) //not being sorted properly due to reference issues
rightCount := InversionCount(right) //not being sorted properly due to reference issues
res := make([]int, 0, len(right)+len(left)) //temp slice to hold the sorted left side and right side
iCount := mergeCount(left, right, &res)
a = res //assigns the original slice with the temp slice values
fmt.Println(a) //a in the end is not sorted properly for most cases
return iCount + leftCount + rightCount
func mergeCount(left, right []int, res *[]int) int
count := 0
for len(left) > 0 || len(right) > 0
if len(left) == 0
*res = append(*res, right...)
break
if len(right) == 0
*res = append(*res, left...)
break
if left[0] <= right[0]
*res = append(*res, left[0])
left = left[1:]
else //Inversion has been found
count += len(left)
*res = append(*res, right[0])
right = right[1:]
return count
func main()
test := []int4,2,3,1,5
fmt.Print(InversionCount(test))
解决此问题的最佳方法是什么?我试图通过强制mergeCount
函数接受数组的引用来做类似于我对res
数组所做的事情,但它看起来很混乱,它会给我带来错误。
【问题讨论】:
【参考方案1】:您要么必须将指针传递给切片,例如:
func InversionCount(a *[]int) int
if len(*a) <= 1
return 0
mid := len(*a) / 2
left := (*a)[:mid]
right := (*a)[mid:]
leftCount := InversionCount(&left) //not being sorted properly due to reference issues
rightCount := InversionCount(&right) //not being sorted properly due to reference issues
res := make([]int, 0, len(right)+len(left)) //temp slice to hold the sorted left side and right side
iCount := mergeCount(left, right, &res)
*a = res
fmt.Println(a) //a in the end is not sorted properly for most cases
return iCount + leftCount + rightCount
playground
或使用copy
并将a = res
更改为copy(a, res)
。
playground
【讨论】:
@DavidTrinh 记得投票并标记对您有帮助的答案。【参考方案2】:与其对切片进行变异,不如让函数返回在合并步骤中获得的切片。
这是这种形式的代码,包括一些类似单元测试的代码,它将有效版本与天真的 O(N^2) 计数进行比较。
package main
import "fmt"
// Inversions returns the input sorted, and the number of inversions found.
func Inversions(a []int) ([]int, int)
if len(a) <= 1
return a, 0
left, lc := Inversions(a[:len(a)/2])
right, rc := Inversions(a[len(a)/2:])
merge, mc := mergeCount(left, right)
return merge, lc + rc + mc
func mergeCount(left, right []int) ([]int, int)
res := make([]int, 0, len(left)+len(right))
n := 0
for len(left) > 0 && len(right) > 0
if left[0] >= right[0]
res = append(res, left[0])
left = left[1:]
else
res = append(res, right[0])
right = right[1:]
n += len(left)
return append(append(res, left...), right...), n
func dumbInversions(a []int) int
n := 0
for i := range a
for j := i + 1; j < len(a); j++
if a[i] < a[j]
n++
return n
func main()
cases := [][]int
,
1,
1, 2, 3, 4, 5,
2, 1, 3, 4, 5,
5, 4, 3, 2, 1,
2, 2, 1, 1, 3, 3, 4, 4, 1, 1,
for _, c := range cases
want := dumbInversions(c)
_, got := Inversions(c)
if want != got
fmt.Printf("Inversions(%v)=%d, want %d\n", c, got, want)
【讨论】:
以上是关于Golang:传入切片作为参考问题的主要内容,如果未能解决你的问题,请参考以下文章