从等效的Python代码转换而来的Go语言代码有什么问题?

huangapple go评论72阅读模式
英文:

what is wrong with go language code converted from equivalent python?

问题

我是你的中文翻译助手,以下是翻译好的内容:

我刚开始学习Go语言,并试图通过实践来学习。我尝试使用归并排序,但不知道哪里出了问题,结果不如预期。我相当确定问题与我使用的切片有关。

我将等效的python代码转换为go代码,Python代码可以正常工作,但是Go代码可能缺少了一些东西(可能是我对切片的理解)。

正常工作的Python代码如下:

def mergeSort(arr):
    if len(arr) > 1:
 
         # 找到数组的中间位置
        mid = len(arr)//2
 
        # 将数组分成两半
        L = arr[:mid]
 
        # 排序第一半
        mergeSort(L)
 
        # 排序第二半
        mergeSort(R)
 
        i = j = k = 0
 
        # 将数据复制到临时数组 L[] 和 R[]
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1
 
        # 检查是否有剩余元素
        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1
 
        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1
 
# 打印列表的代码
 
 
def printList(arr):
    for i in range(len(arr)):
        print(arr[i], end=" ")
    print()

# 主程序
arr = [457, 4, 0, 500, -8, 6, 5, -20, -93, 50, 5, 1, 6, 10, 54, 7, 13, 10, -5, 50, 500, 8, 4, -1, -99, 5, 0, 0, -899]
printList(mergeSort(arr))

转换为等效的Go代码:

package main
import "fmt"

func main() {
    intArr := []int{457, 4, 0, 500, -8, 6, 5, -20, -93, 50, 5, 1, 6, 10, 54, 7, 13, 10, -5, 50, 500, 8, 4, -1, -99, 5, 0, 0, -899}
    fmt.Println(mergeSort(intArr))
}

func mergeSort(arr []int) []int {
    if len(arr) > 1 {

        // 找到数组的中间位置
        mid := int(len(arr) / 2)

        // 将数组分成两半
        L := arr[:mid]

        // 排序第一半
        mergeSort(L)

        // 排序第二半
        mergeSort(R)

        i, j, k := 0, 0, 0

        // 将数据复制到临时数组 L[] 和 R[]
        for i < len(L) && j < len(R) {
            if L[i] < R[j] {
                arr[k] = L[i]
                i++
            } else {
                arr[k] = R[j]
                j++
            }
            k++
        }

        // 检查是否有剩余元素
        for i < len(L) {
            arr[k] = L[i]
            i++
            k++
        }

        for j < len(R) {
            arr[k] = R[j]
            j++
            k++
        }
    }
    return arr
}

但是Go代码的输出结果如下:

[-899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899]
英文:

I am new to Go Language and trying to learn it by doing.
tried with MergeSort but some how I am missing something and result is not as expected.
I am pretty sure it has something to do with slices I am using.

converted equivalent python code to go python works but go code missed something (in terms of my understanding to slice may be)

working Python Code

def mergeSort(arr):
    if len(arr) &gt; 1:
 
         # Finding the mid of the array
        mid = len(arr)//2
 
        # Dividing the array elements
        L = arr[:mid]
 
        # into 2 halves
        R = arr[mid:]
 
        # Sorting the first half
        mergeSort(L)
 
        # Sorting the second half
        mergeSort(R)
 
        i = j = k = 0
 
        # Copy data to temp arrays L[] and R[]
        while i &lt; len(L) and j &lt; len(R):
            if L[i] &lt; R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1
 
        # Checking if any element was left
        while i &lt; len(L):
            arr[k] = L[i]
            i += 1
            k += 1
 
        while j &lt; len(R):
            arr[k] = R[j]
            j += 1
            k += 1
 
# Code to print the list
 
 
def printList(arr):
    for i in range(len(arr)):
        print(arr[i], end=&quot; &quot;)
    print()

# Driver Code
arr = [457, 4, 0, 500, -8, 6, 5, -20, -93, 50, 5, 1, 6, 10, 54, 7, 13, 10, -5, 50, 500, 8, 4, -1, -99, 5, 0, 0, -899]
printList(mergeSort(arr))
 

Converted equivalent Go Code

package main
import &quot;fmt&quot;

func main() {
    intArr := []int{457, 4, 0, 500, -8, 6, 5, -20, -93, 50, 5, 1, 6, 10, 54, 7, 13, 10, -5, 50, 500, 8, 4, -1, -99, 5, 0, 0, -899}
    fmt.Println(mergeSort(intArr))
}

func mergeSort(arr []int) []int {
    if len(arr) &gt; 1 {

        // Finding the mid of the array
        mid := int(len(arr) / 2)

        // Dividing the array elements
        L := arr[:mid]

        // into 2 halves
        R := arr[mid:]

        // Sorting the first half
        mergeSort(L)

        // Sorting the second half
        mergeSort(R)

        i, j, k := 0, 0, 0

        // Copy data to temp arrays L[] and R[]
        for i &lt; len(L) &amp;&amp; j &lt; len(R) {
            if L[i] &lt; R[j] {
                arr[k] = L[i]
                i++
            } else {
                arr[k] = R[j]
                j++
            }
            k++
        }

        // Checking if any element was left
        for i &lt; len(L) {
            arr[k] = L[i]
            i++
            k++
        }

        for j &lt; len(R) {
            arr[k] = R[j]
            j++
            k++
        }
    }
    return arr
}

but output is from Go code

[-899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899 -899]

答案1

得分: 1

数组切片在Go语言中不会分配新的数组。L、R和arr指的是同一个底层数组。
你可以使用"copy"函数来深度克隆切片:

func mergeSort(arr []int) []int {
    if len(arr) > 1 {        

        // 找到数组的中间位置
        mid := int(len(arr) / 2)        

        // 将数组分成两半
        L := make([]int, mid)
        copy(L, arr[:mid])        

        // into 2 halves
        R := make([]int, len(arr)-mid)
        copy(R, arr[mid:])        

        // 对第一半进行排序
        mergeSort(L)        

        // 对第二半进行排序
        mergeSort(R)        

        i, j, k := 0, 0, 0        

        // 将数据复制到临时数组L[]和R[]
        for i < len(L) && j < len(R) {
            if L[i] < R[j] {
                arr[k] = L[i]
                i++
            } else {
                arr[k] = R[j]
                j++
            }
            k++
        }        

        // 检查是否有剩余元素
        for i < len(L) {
            arr[k] = L[i]
            i++
            k++
        }        

        for j < len(R) {
            arr[k] = R[j]
            j++
            k++
        }
    }
    return arr
}

以上是对数组进行归并排序的示例代码。

英文:

Array slicing does not allocate new arrays in go. L, R and arr refers to the same underlying array.
You can use "copy" to deep clone the slice:

    func mergeSort(arr []int) []int {
if len(arr) &gt; 1 {        
// Finding the mid of the array
mid := int(len(arr) / 2)        
// Dividing the array elements
L := make([]int, mid)
copy(L, arr[:mid])        
// into 2 halves
R := make([]int, len(arr)-mid)
copy(R, arr[mid:])        
// Sorting the first half
mergeSort(L)        
// Sorting the second half
mergeSort(R)        
i, j, k := 0, 0, 0        
// Copy data to temp arrays L[] and R[]
for i &lt; len(L) &amp;&amp; j &lt; len(R) {
if L[i] &lt; R[j] {
arr[k] = L[i]
i++
} else {
arr[k] = R[j]
j++
}
k++
}        
// Checking if any element was left
for i &lt; len(L) {
arr[k] = L[i]
i++
k++
}        
for j &lt; len(R) {
arr[k] = R[j]
j++
k++
}
}
return arr
}

huangapple
  • 本文由 发表于 2022年7月31日 23:36:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/73184618.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定