如何在Go中反转数组?

时间:2013-10-08 05:02:16

标签: go

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(数据接口)接口的含义。

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

16 个答案:

答案 0 :(得分:83)

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

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

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

答案 1 :(得分:18)

通常,要对整数数组进行排序,请将它们包装在IntSlice中,该Len定义方法LessSwapsort.Sortsort.Reverse反过来使用这些方法。 Len所做的是它采用定义LessSwapLess的现有类型,但它将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方法。因此,如果您在其上调用{{1}},调用{{1}},则会按降序排序。

答案 2 :(得分:9)

我已经迟到了2年,但只是为了娱乐和兴趣,我想贡献一个&#34; oddball&#34;溶液

假设任务确实是要反转列表,那么原始性能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]

同样,这是为了好玩而不是制作。它不仅速度慢,而且如果列表太大,它将溢出堆栈。我刚刚测试了,它将反转一百万个int的列表,但崩溃了一千万个。

答案 3 :(得分:8)

首先,如果你想要反转数组,那就这样做,

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和Sort

的描述
func Reverse(data Interface) Interface
func Sort(data Interface)
  

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

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

答案 4 :(得分:5)

如果要反转数组,可以按相反顺序查看。由于语言中没有“反向范围”原语(至少现在还没有),你必须做这样的事情(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”的源代码之前,我的想法是一样的。

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

答案 5 :(得分:4)

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

//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)
    }
}

答案 6 :(得分:3)

func Reverse(data Interface) Interface

这意味着它需要sort.Interface并返回另一个sort.Interface - 它实际上并没有进行任何排序。例如,如果您传入sort.IntSlice(基本上是[]int可以传递给sort.Sort以按升序排序),您将获得新的sort.Interface而是按降序对整数进行排序。

顺便说一句,如果您点击the documentation中的功能名称,它会直接链接到Reverse sort.Interface。如您所见,它只包含您传入的Reverse,因此从sort.Interface返回的值将获取原始Less的所有方法。唯一不同的方法是Less方法,它返回嵌入式sort.Interface上{{1}}方法的反面。有关嵌入字段的详细信息,请参阅the source

答案 7 :(得分:2)

这是另一种方法

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

答案 8 :(得分:1)

这是一个简单的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

答案 9 :(得分:0)

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

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

答案 10 :(得分:0)

来自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]
}

答案 11 :(得分:0)

这是我的solution

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)
}

答案 12 :(得分:0)

这是一个使用 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

答案 13 :(得分:-1)

这是我反转阵列的解决方案:

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
}

您可以在运动场the go playground上尝试此解决方案

package main

import "fmt"

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

    fmt.Println(reverse_array(array)) // prints [d c b a]
}

答案 14 :(得分:-1)

func main() {
x := []int{1, 2, 3, 4, 5, 6, 7, 8, 9,10,20,19,17,23}
arrlength := len(x)
for i, _ := range x {
    j := arrlength-1 - i
    fmt.Println(x)
    if j-i < 1 {
        break
    }
    x[i], x[j] = x[j], x[i]
}}

我刚刚去了一半数组,因为中间元素的索引之间的差异将是 1 或 0 。在中间位置停止交换。我不需要迭代价值

答案 15 :(得分:-5)

不要反转它,将其保留为现在,然后向后迭代它。