使用sort.Slice函数对切片的一部分进行排序。

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

golang sort part of a slice using sort.Slice

问题

这是一个关于在Golang中使用sort.Slice对切片进行排序的问题。你想要对切片的一部分进行排序,但是你发现原来的代码并不能按照你的预期工作。你提供了一个新的代码片段,并想知道为什么它可以正确地排序切片的一部分。

首先,让我们来看一下你的原始代码:

func sortPartly(nums []int, p int) {
	sort.Slice(nums[p:], func(i, j int) bool {
		if nums[i] < nums[j] {
			return true
		} else {
			return false
		}
	})
}

这段代码的问题在于,它只比较了切片中从索引p开始的元素,但是在排序时并没有考虑到这一点。因此,它并不能正确地排序切片的一部分。

接下来,让我们来看一下你修改后的代码:

func sortPartly(nums []int, p int) {
	sort.Slice(nums[p:], func(i, j int) bool {
		if nums[i+p] < nums[j+p] {
			return true
		} else {
			return false
		}
	})
}

这段代码在比较元素时,使用了i+pj+p作为索引。这样做的目的是确保比较的是切片中从索引p开始的元素,而不是整个切片。通过这种方式,你可以正确地对切片的一部分进行排序。

希望这样解释可以帮助你理解为什么修改后的代码可以正确地排序切片的一部分。如果你还有其他问题,请随时提问。

英文:

It's easy to sort a slice using sort.Slice in Golang, for example

func sortAll(nums []int) {
	sort.Slice(nums, func(i, j int) bool {
		if nums[i] &lt; nums[j] {
			return true
		} else {
			return false
		}
	})
}

input : []int{2, 0, 1, 0, 1, 2, 2, 2}
output:[0 0 1 1 2 2 2 2]

It works great.

However, if I want to sort a slice from some certain position, which means I just want to sort part of the slice. I used this piece of code:

func sortPartly(nums []int, p int) {
	sort.Slice(nums[p:], func(i, j int) bool {
		if nums[i] &lt; nums[j] {
			return true
		} else {
			return false
		}
	})
}

With the same input, I use sortPartly(nums, 1) to set the position to start sorting to be 1. And I got output [2 0 1 1 2 2 2 0] which isn't in order from nums[1],the output should be [2 0 0 1 1 2 2 2]

After some debugging, I happend to write this piece of code below, it worked just as I wanted. But I don't understand why this code works

func sortPartly(nums []int, p int) {
	sort.Slice(nums[p:], func(i, j int) bool {
		if nums[i+p] &lt; nums[j+p] {
			return true
		} else {
			return false
		}
	})
}

I have a toy code to save your time, can anyone help me explain why this code works. Go Playground

答案1

得分: 1

以下是问题的翻译结果:

这是问题中有效的代码:

func sortPartly(nums []int, p int) {
    sort.Slice(nums[p:], func(i, j int) bool {
        if nums[i+p] < nums[j+p] {
            return true
        } else {
            return false
        }
    })
}

这个函数对切片 nums[p:] 进行排序。这个切片与 nums 共享一个底层数组,但是在该底层数组中的元素使用不同的索引。在索引为0的位置的元素在 nums 中的索引为 p,在索引为1的位置的元素在 nums 中的索引为 p + 1,依此类推。因为 sort.Slice 使用的是对切片 nums[p:] 的索引,并且匿名函数引用了切片 nums,所以匿名函数必须通过添加 p 来调整索引。

通过声明要排序的切片来消除索引调整。在匿名函数中引用该切片。

func sortPartly(nums []int, p int) {
    t := nums[p:]
    sort.Slice(t, func(i, j int) bool {
        if t[i] < t[j] {
            return true
        } else {
            return false
        }
    })
}

注意,tnums 共享一个底层数组。对 t 进行排序会对 nums 中的元素进行排序。

额外建议:将 if boolValue { return true } else { return false } 的结构简化为 return boolValue

func sortPartly(nums []int, p int) {
    t := nums[p:]
    sort.Slice(t, func(i, j int) bool {
        return t[i] < t[j]
    })
}

希望对你有帮助!

英文:

Here's the code that works from the question:

func sortPartly(nums []int, p int) {
    sort.Slice(nums[p:], func(i, j int) bool {
        if nums[i+p] &lt; nums[j+p] {
            return true
        } else {
            return false
        }
    })
}

This function sorts the slice nums[p:]. This slice shares a backing array with nums, but uses different indices for the elements in that backing array. The element at index 0 is at index p in nums. The element at index 1 is at index p + 1 in nums and so on. Because sort.Slice uses indices into the slice nums[p:] and the anonymous function refers to slice nums, the anonymous function must adjust the indices by adding p.

Eliminate the index adjustment by declaring the slice to sort. Refer to that slice in the anonymous function.

func sortPartly(nums []int, p int) {
    t := nums[p:]
    sort.Slice(t, func(i, j int) bool {
        if t[i] &lt; t[j] {
            return true
        } else {
            return false
        }
    })
}

Note that t shares a backing array with nums. Sorting t sorts elements in nums.

Bonus suggestion: Simplify the construct if boolValue { return true } else { return false } to return boolValue.

func sortPartly(nums []int, p int) {
	t := nums[p:]
	sort.Slice(t, func(i, j int) bool {
		return t[i] &lt; t[j]
	})
}

huangapple
  • 本文由 发表于 2022年9月10日 23:37:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/73673104.html
匿名

发表评论

匿名网友

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

确定