英文:
What is wrong with the following merge sort algorithm?
问题
根据问题描述,我在以下算法中找不到问题所在。这是mergesort的辅助函数,即用于合并排序数组的函数。
func Merge(toSort *[]int, p, q, r int) {
arr := *toSort
L := arr[p:q]
R := arr[q:r+1]
fmt.Println(L)
fmt.Println(R)
i := 0
j := 0
for index := p; index <= r; index++ {
if i >= len(L) {
arr[index] = R[j]
j += 1
continue
} else if j >= len(R) {
arr[index] = L[i]
i += 1
continue
}
if L[i] > R[j] {
fmt.Println("right smaller")
arr[index] = R[j]
j += 1
continue
}
if L[i] <= R[j] {
fmt.Println("left smaller")
arr[index] = L[i]
i += 1
continue
}
}
}
对于arr := []int{1,7,14,15,44,65,79,2,3,6,55,70}
,它的输出是[1 2 2 2 2 2 2 2 3 6 55 70]
。
这是问题的Go Playground链接。
这个函数的JavaScript等效版本按预期工作,但我不知道为什么它在Go
中不起作用。
谢谢
英文:
As the question states, I'm having trouble finding where is the issue within the following algorithm. It is the aux function for mergesort, i.e. the one used for combining sorted arrays.
func Merge(toSort *[]int, p, q, r int) {
arr := *toSort
L := arr[p:q]
R := arr[q:r+1]
fmt.Println(L)
fmt.Println(R)
i := 0
j := 0
for index := p; index <= r; index++ {
if i >= len(L) {
arr[index] = R[j]
j += 1
continue
} else if j >= len(R) {
arr[index] = L[i]
i += 1
continue
}
if L[i] > R[j] {
fmt.Println("right smaller")
arr[index] = R[j]
j += 1
continue
}
if L[i] <= R[j] {
fmt.Println("left smaller")
arr[index] = L[i]
i += 1
continue
}
}
}
For arr := []int{1,7,14,15,44,65,79,2,3,6,55,70}
it gives as output [1 2 2 2 2 2 2 2 3 6 55 70]
.
The JavaScript equivalent for this function works as expected, but I don't know why it isn't working in Go
Thank you
答案1
得分: 2
Golang切片是通过引用传递的。因此,你不需要在函数中传递指针,但是你需要显式地复制L
和R
,否则会合并到一个完全不同的切片中。你目前正在写入从中获取值的相同底层内存。
英文:
Golang slices are passed by reference. So you don't need to pass a pointer into the function in the first place, but you do need to take explicit copies of L
and R
or else merge into a different slice entirely. You are currently writing into the same underlying memory from which you are getting your values.
答案2
得分: 1
代码像 L := arr[p:q]
这样的形式不会创建副本。我猜想你在对 arr
进行赋值时覆盖了 L 和 R 部分。请查看 http://blog.golang.org/slices 了解切片的工作原理(例如,你基本上不会将 toSort *[]int
这样的东西写成 []int
,因为 []int
几乎就像是指针)。
这个链接似乎可以解决问题:http://play.golang.org/p/vPo2ZKXtI9
英文:
Code like L := arr[p:q]
does not create a copy. I suppose you are overwriting your L and R parts during the assignments to arr
. Have a look at http://blog.golang.org/slices to understand how slices work. (E.g. you'll basically never write stuff like toSort *[]int
as []int
is almost kinda pointer)
This seems to work: http://play.golang.org/p/vPo2ZKXtI9
答案3
得分: 1
你不需要所有的索引:切片已经是数组的视图。下面是一个完整的示例,仅使用切片操作:
package main
import "fmt"
// Merge将两个已排序的递增切片合并成一个已排序的递增切片。
func Merge(a, b []int) []int {
res := make([]int, 0, len(a)+len(b))
for len(a) > 0 || len(b) > 0 {
if len(b) == 0 || len(a) > 0 && a[0] <= b[0] {
res = append(res, a[0])
a = a[1:]
} else {
res = append(res, b[0])
b = b[1:]
}
}
return res
}
func main() {
a := []int{1, 2, 5, 6, 3, 4, 7, 9}
fmt.Println(Merge(a[:4], a[4:]))
}
这段代码演示了如何使用切片操作来合并两个已排序的递增切片。函数Merge
接受两个切片参数a
和b
,并返回一个合并后的已排序递增切片。在Merge
函数中,我们使用了切片操作a[:4]
和a[4:]
来将切片a
分成两部分。然后,我们调用Merge
函数将这两部分切片合并起来,并打印结果。
英文:
You don't need all the indexes: slices are already views into an array. Here's a complete example using purely slice manipulation:
package main
import "fmt"
// Merge takes two sorted, increasing slices of ints and
// returns a slice combining them into a single sorted, increasing
// slice.
func Merge(a, b []int) []int {
res := make([]int, 0, len(a)+len(b))
for len(a) > 0 || len(b) > 0 {
if len(b) == 0 || len(a) > 0 && a[0] <= b[0] {
res = append(res, a[0])
a = a[1:]
} else {
res = append(res, b[0])
b = b[1:]
}
}
return res
}
func main() {
a := []int{1, 2, 5, 6, 3, 4, 7, 9}
fmt.Println(Merge(a[:4], a[4:]))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论