68

http://play.golang.org/p/W70J4GU7nA

  s := []int{5, 2, 6, 3, 1, 4}
  sort.Reverse(sort.IntSlice(s))
  fmt.Println(s)
  // 5, 2, 6, 3, 1, 4

很难理解 func Reverse(data Interface) Interface 中的含义。

如何反转数组?我不需要排序。

4

15 回答 15

140

老实说,这个很简单,我就这样写出来:

package main

import "fmt"

func main() {

    s := []int{5, 2, 6, 3, 1, 4}

    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
        s[i], s[j] = s[j], s[i]
    }

    fmt.Println(s)
}

http://play.golang.org/p/vkJg_D1yUb

(其他答案很好地解释sort.Interface了以及如何使用它;所以我不会重复。)

于 2013-10-08T05:36:11.703 回答
31

通常,要对整数数组进行排序,您可以将它们包装在 中IntSlice,它定义了方法LenLessSwap。这些方法又被sort.Sort. 它的作用是sort.Reverse它采用定义LenLess和的现有类型Swap,但它用Less一个始终与底层相反的新方法替换该方法Less

type reverse struct {
    // This embedded Interface permits Reverse to use the methods of
    // another Interface implementation.
    Interface
}

// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
    return r.Interface.Less(j, i)
}

// Reverse returns the reverse order for data.
func Reverse(data Interface) Interface {
    return &reverse{data}
}

所以当你写的时候sort.Reverse(sort.IntSlice(s)),发生的事情是你得到了这个新的、“修改过的” IntSlice,它的Less方法被替换了。因此,如果您调用sort.Sort它,它调用Less,它将按降序排序。

于 2013-10-08T05:34:43.307 回答
18

我迟到了 2 年,但只是为了乐趣和兴趣,我想贡献一个“古怪”的解决方案。

假设任务确实是反转列表,那么对于原始性能bgp的解决方案可能是无与伦比的。它通过前后交换数组项来简单有效地完成工作,这种操作在数组和切片的随机访问结构中是有效的。

在函数式编程语言中,惯用的方法通常涉及递归。这在 Go 中看起来有点奇怪,并且性能会很差。也就是说,这是一个递归数组反转函数(在一个小测试程序中):

package main

import (
    "fmt"
)

func main() {
    myInts := []int{ 8, 6, 7, 5, 3, 0, 9 }
    fmt.Printf("Ints %v reversed: %v\n", myInts, reverseInts(myInts))
}

func reverseInts(input []int) []int {
    if len(input) == 0 {
        return input
    }
    return append(reverseInts(input[1:]), input[0]) 
}

输出:

Ints [8 6 7 5 3 0 9] reversed: [9 0 3 5 7 6 8]

同样,这是为了娱乐而不是生产。不仅速度慢,而且如果列表太大,它会溢出堆栈。我刚刚测试过,它会反转 100 万int的列表,但会在 1000 万时崩溃。

于 2015-04-03T22:45:49.260 回答
14

首先,如果要反转数组,请这样做,

for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
    a[i], a[j] = a[j], a[i]
}

然后,看一下golang.org中Reverse的用法

package main

import (
    "fmt"
    "sort"
)

func main() {
    s := []int{5, 2, 6, 3, 1, 4} // unsorted
    sort.Sort(sort.Reverse(sort.IntSlice(s)))
    fmt.Println(s)
}

// output
// [6 5 4 3 2 1]

并查看 Reverse and Sort 的描述

func Reverse(data Interface) Interface
func Sort(data Interface)

Sort 对数据进行排序。它对 data.Len 进行一次调用以确定 n,然后对 data.Less 和 data.Swap 进行 O(n*log(n)) 调用。不能保证排序是稳定的。

所以,如您所知,Sort 不仅仅是一种排序算法,您可以将其视为一个工厂,当您使用 Reverse 时,它​​只是返回一个反向排序算法,Sort 只是进行排序。

于 2017-03-02T01:58:32.530 回答
7

这是一个更通用的切片反转功能。如果输入不是切片,它会恐慌。

//panic if s is not a slice
func ReverseSlice(s interface{}) {
    size := reflect.ValueOf(s).Len()
    swap := reflect.Swapper(s)
    for i, j := 0, size-1; i < j; i, j = i+1, j-1 {
        swap(i, j)
    }
}
于 2017-05-10T03:05:41.607 回答
4

如果你想反转数组,你可以按相反的顺序遍历它。由于语言中没有“反向范围”原语(至少现在还没有),你必须做这样的事情(http://play.golang.org/p/AhvAfMjs_7):

s := []int{5, 2, 6, 3, 1, 4}
for i := len(s) - 1; i >= 0; i-- {
    fmt.Print(s[i])
    if i > 0 {
        fmt.Print(", ")
    }
}
fmt.Println()

关于是否很难理解是什么sort.Reverse(data Interface) Interface,我是这么想的,直到我看到“ http://golang.org/src/pkg/sort/sort.go ”的源代码。

它只是使排序所需的比较“反过来”。

于 2013-10-08T05:46:59.767 回答
4

这是一个简单的 Go 解决方案,它使用一种高效(无额外内存)的方法来反转数组:

i := 0
j := len(nums) - 1
for i < j {
    nums[i], nums[j] = nums[j], nums[i]
    i++
    j--
}

这个想法是,反转一个数组相当于交换每个元素及其在中心的镜像。

https://play.golang.org/p/kLFpom4LH0g

于 2018-12-12T04:54:54.313 回答
4

这是另一种方法

func main() {
    example := []int{1, 25, 3, 5, 4}
    sort.SliceStable(example, func(i, j int) bool {
        return true
    })
    fmt.Println(example)
}

https://play.golang.org/p/-tIzPX2Ds9z

于 2018-06-16T00:13:16.837 回答
2
func Reverse(data Interface) Interface

这意味着它需要一个sort.Interface并返回另一个sort.Interface——它实际上并没有做任何排序。例如,如果你传入sort.IntSlice(本质上是一个[]int可以传递给sort.Sort它以按升序对其进行排序的 a),你将得到一个新sort.Interface的,它以降序对 int 进行排序。

顺便说一句,如果您单击文档中的函数名称,它会直接链接. Reverse如您所见,它只是包装了sort.Interface您传入的,因此从返回的值Reverse获取原始的所有方法sort.Interface。唯一不同的方法是返回与嵌入的方法Less相反的方法。有关嵌入字段的详细信息,请参阅语言规范的这一部分。Lesssort.Interface

于 2013-10-08T05:34:09.780 回答
1

来自Golang wiki SliceTricks

用相同的元素但以相反的顺序替换切片的内容:

for i := len(a)/2-1; i >= 0; i-- {
  opp := len(a)-1-i
  a[i], a[opp] = a[opp], a[i]
}

同样的事情,除了有两个索引:

for left, right := 0, len(a)-1; left < right; left, right = left+1, right-1 {
  a[left], a[right] = a[right], a[left]
}
于 2019-09-07T04:52:23.827 回答
1

这是一种使用方法append

package main
import "fmt"

func main() {
   a := []int{10, 20, 30, 40, 50}
   for n := len(a) - 2; n >= 0; n-- {
      a = append(a[:n], append(a[n + 1:], a[n])...)
   }
   fmt.Println(a)
}

绘制步骤:

10 20 30 40 50
10 20 30    50 40
10 20       50 40 30
10          50 40 30 20
            50 40 30 20 10
于 2021-05-03T00:52:01.813 回答
0

要反转一个数组,迭代到它的中点,并用它的“镜像元素”交换每个元素:

func main() {
    xs := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    itemCount := len(xs)
    for i := 0; i < itemCount/2; i++ {
        mirrorIdx := itemCount - i -1
        xs[i], xs[mirrorIdx] = xs[mirrorIdx], xs[i]
    }
    fmt.Printf("xs: %v\n", xs)
}

https://play.golang.org/p/JeSApt80_k

于 2017-05-02T08:44:46.403 回答
-1

这是我的解决方案

package main

import (
	"fmt"
)

func main() {
	var numbers = [10]int {1,2,3,4,5,6,7,8,9,10}
	var reverseNumbers [10]int
	j:=0
	for i:=len(numbers)-1; i>=0 ; i-- {
		reverseNumbers[j]=numbers[i]
		j++	
	}
	fmt.Println(reverseNumbers)
}

于 2020-06-16T01:56:19.940 回答
-2

这是我反转数组的解决方案:

func reverse_array(array []string) []string {
    lenx := len(array) // lenx holds the original array length
    reversed_array := make([]string, lenx) // creates a slice that refer to a new array of length lenx

    for i := 0; i < lenx; i++ {
        j := lenx - (i + 1) // j initially holds (lenx - 1) and decreases to 0 while i initially holds 0 and increase to (lenx - 1)
        reversed_array[i] = array[j]
    }

    return reversed_array
}

您可以在 go playground上尝试此解决方案

package main

import "fmt"

func main() {
    array := []string{"a", "b", "c", "d"}

    fmt.Println(reverse_array(array)) // prints [d c b a]
}
于 2019-06-27T22:19:55.097 回答
-3

不要反转它,让它保持现在,然后向后迭代它。

于 2017-10-20T11:08:47.107 回答