How do I reverse an array in Go?

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

How do I reverse an array in Go?

问题

以下是您提供的代码的翻译:

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中,很难理解它的含义。

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

英文:

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

It is hard to understand what it means in func Reverse(data Interface) Interface .

How do I reverse an array? I do not need to sort.

答案1

得分: 160

老实说,这个问题简单到我只需要像这样写出来就可以了:

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以及如何使用它,所以我就不再重复了。)

英文:

Honestly this one is simple enough that I'd just write it out like this:

package main

import &quot;fmt&quot;

func main() {

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

	for i, j := 0, len(s)-1; i &lt; 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

(The other answers do a good job of explaining sort.Interface and how to use it; so I won't repeat that.)

答案2

得分: 31

通常,要对整数数组进行排序,您需要将它们包装在IntSlice中,该类型定义了LenLessSwap方法。这些方法又被sort.Sort使用。而sort.Reverse的作用是,它接受一个已定义了LenLessSwap方法的现有类型,并将其中的Less方法替换为一个始终与底层Less方法相反的新方法:

type reverse struct {
    // 这个嵌入的Interface允许Reverse使用另一个Interface实现的方法。
    Interface
}

// Less返回嵌入实现的Less方法的相反值。
func (r reverse) Less(i, j int) bool {
    return r.Interface.Less(j, i)
}

// Reverse返回数据的逆序。
func Reverse(data Interface) Interface {
    return &reverse{data}
}

因此,当您编写sort.Reverse(sort.IntSlice(s))时,发生的情况是您获得了这个新的、'修改过的'IntSlice,它的Less方法被替换了。因此,如果您对其调用sort.Sort,它将按降序进行排序。

英文:

Normally, to sort an array of integers you wrap them in an IntSlice, which defines the methods Len, Less, and Swap. These methods are in turn used by sort.Sort. What sort.Reverse does is that it takes an existing type that defines Len, Less, and Swap, but it replaces the Less method with a new one that is always the inverse of the underlying 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&#39;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 &amp;reverse{data}
}

So when you write sort.Reverse(sort.IntSlice(s)), whats happening is that you're getting this new, 'modified' IntSlice that has it's Less method replaced. So if you call sort.Sort on it, which calls Less, it will get sorted in decreasing order.

答案3

得分: 21

我晚了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]

再次强调,这只是为了好玩,而不是用于生产。它不仅速度慢,而且如果列表太大,会导致堆栈溢出。我刚刚测试了一下,它可以反转包含1百万个int的列表,但在1千万个时会崩溃。

英文:

I'm 2 years late, but just for fun and interest I'd like to contribute an "oddball" solution.

Assuming the task really is to reverse a list, then for raw performance bgp's solution is probably unbeatable. It gets the job done simply and effectively by swapping array items front to back, an operation that's efficient in the random-access structure of arrays and slices.

In Functional Programming languages, the idiomatic approach would often involve recursion. This looks a bit strange in Go and will have atrocious performance. That said, here's a recursive array reversal function (in a little test program):

package main

import (
	&quot;fmt&quot;
)

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

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

Output:

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

Again, this is for fun and not production. Not only is it slow, but it will overflow the stack if the list is too large. I just tested, and it will reverse a list of 1 million ints but crashes on 10 million.

答案4

得分: 16

首先,如果你想要反转数组,可以这样做:

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} // 未排序的数组
    sort.Sort(sort.Reverse(sort.IntSlice(s)))
    fmt.Println(s)
}

// 输出
// [6 5 4 3 2 1]

再来看一下Reverse和Sort的描述:

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

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

所以,正如你所知,Sort不仅仅是一个排序算法,你可以将其视为一个工厂,当你使用Reverse时,它只是返回一个反转的排序算法,而Sort则负责进行排序。

英文:

First of all, if you want to reverse the array, do like this,

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

Then, look at the usage of Reverse in golang.org

package main

import (
    &quot;fmt&quot;
    &quot;sort&quot;
)

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]

And look at the description of Reverse and Sort

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

> Sort sorts data. It makes one call to data.Len to determine n, and O(n*log(n)) calls to data.Less and data.Swap. The sort is not guaranteed to be stable.

So, as you know, Sort is not just a sort algorithm, you can view it as a factory, when you use Reverse it just return a reversed sort algorithm, Sort is just doing the sorting.

答案5

得分: 7

这是一个更通用的切片反转函数。如果输入不是切片类型,它会引发 panic 错误。

// 如果 s 不是切片类型,引发 panic 错误
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)
    }
}
英文:

This is a more generic slice reverse function. It will panic if input is not a slice.

//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 &lt; j; i, j = i+1, j-1 {
		swap(i, j)
	}
}

答案6

得分: 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"的源代码。

它只是使排序所需的比较"反过来"进行。

英文:

If you want to reverse the array, you can just go through it in reverse order. Since there is no "reverse range" primitive in the language (at least not yet), you must do something like this (http://play.golang.org/p/AhvAfMjs_7):

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

Regarding whether it is hard to understand what sort.Reverse(data Interface) Interface does, I thought the same until I saw the source code from "http://golang.org/src/pkg/sort/sort.go".

It just makes the comparisons required for the sorting to be made "the other way around".

答案7

得分: 5

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

英文:

Here is a simple Go solution that uses an efficient (no extra memory) approach to reverse an array:

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

The idea is that reversing an array is equivalent to swapping each element with its mirror image across the center.

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

答案8

得分: 3

这是另一种方法来完成它

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

英文:

Here is another way to do it

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

答案9

得分: 2

func Reverse(data Interface) Interface

这意味着它接受一个 sort.Interface 并返回另一个 sort.Interface -- 它本身并不执行任何排序操作。例如,如果你传入 sort.IntSlice(它本质上是一个可以传递给 sort.Sort 以按升序排序的 []int),你将得到一个新的 sort.Interface,它以降序排序整数。

顺便说一下,如果你在文档中点击函数名,它会直接链接到 Reverse源代码。正如你所见,它只是包装了你传入的 sort.Interface,所以从 Reverse 返回的值具有原始 sort.Interface 的所有方法。唯一不同的方法是 Less 方法,它返回嵌入的 sort.InterfaceLess 方法的相反值。有关嵌入字段的详细信息,请参阅语言规范的这一部分

英文:
func Reverse(data Interface) Interface

This means that it takes a sort.Interface and returns another sort.Interface -- it doesn't actually doing any sorting itself. For example, if you pass in sort.IntSlice (which is essentially a []int that can be passed to sort.Sort to sort it in ascending order) you'll get a new sort.Interface which sorts the ints in descending order instead.

By the way, if you click on the function name in the documentation, it links directly to the source for Reverse. As you can see, it just wraps the sort.Interface that you pass in, so the value returned from Reverse gets all the methods of the original sort.Interface. The only method that's different is the Less method which returns the opposite of the Less method on the embedded sort.Interface. See this part of the language spec for details on embedded fields.

答案10

得分: 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]
> }

英文:

From Golang wiki SliceTricks:

> To replace the contents of a slice with the same elements but in
> reverse order:
>
> for i := len(a)/2-1; i >= 0; i-- {
> opp := len(a)-1-i
> a[i], a[opp] = a[opp], a[i]
> }
>
> The same thing, except with two indices:
>
> for left, right := 0, len(a)-1; left < right; left, right = left+1, right-1 {
> a[left], a[right] = a[right], a[left]
> }

答案11

得分: 1

简单的解决方案,不涉及数学。像这个解决方案一样,这种方法效率低下,因为它进行了太多的分配和垃圾回收。适用于非关键代码,其中清晰度比性能更重要。游乐场:https://go.dev/play/p/dQGwrc0Q9ZA

arr := []int{1, 3, 4, 5, 6}
var rev []int
for _, n := range arr {
    rev = append([]int{n}, rev...)
}
fmt.Println(arr)
fmt.Println(rev)
英文:

Simple solution without involving math. Like this solution, this is inefficient as it does too much allocation and garbage collection. Good for non-critical code where clarity is more important than performance. Playground: https://go.dev/play/p/dQGwrc0Q9ZA

arr := []int{1, 3, 4, 5, 6}
var rev []int
for _, n := range arr {
	rev = append([]int{n}, rev...)
}
fmt.Println(arr)
fmt.Println(rev)

答案12

得分: 1

如果你想打印反向数组,非常简单。

使用从长度开始的索引,递减i。

例如:

a := []int{5, 4, 12, 7, 15, 9}
for i := 0; i <= len(a)-1; i++ {
    fmt.Println(a[len(a)-(i+1)])
}

你可以在这里运行代码:https://go.dev/play/p/bmyFh7-_VCZ

英文:

Its very simple if you want to print reverse array

Use Index from length doing i--

ex.

a := []int{5, 4, 12, 7, 15, 9}
	for i := 0; i &lt;= len(a)-1; i++ {
		fmt.Println(a[len(a)-(i+1)])
	}

https://go.dev/play/p/bmyFh7-_VCZ

答案13

得分: 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

英文:

To reverse an array in place, iterate to its mid-point, and swap each element with its "mirror element":

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

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

答案14

得分: 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
英文:

Here is a method using append:

package main
import &quot;fmt&quot;

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

Drawing of the steps:

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

答案15

得分: 0

这个答案主要是给那些希望在for循环中只使用一个变量而不是两个变量(比如i和j)来编写这段代码的初学者。

package main

import "fmt"

func main() {
	array := []int{45, 17, 43, 67, 21, 4, 97, 44, 54, 98, 665}
	fmt.Println("初始数组:", array)
	loop_iteration := len(array)
	if len(array)%2 == 0 {
		loop_iteration = (len(array) / 2) - 1
	} else {
		loop_iteration = int(len(array) / 2)  //这将给出该浮点数的较小整数值。
	}
	for i := 0; i <= loop_iteration; i++ {
		array[i], array[(len(array)-1)-i] = array[(len(array)-1)-i], array[i]
	}
	fmt.Println("反转后的数组:", array)
}

希望对你有帮助!

英文:

This answer is mainly for those beginners who wish to write this code using only one variable in the for loop instead of using two variables (like i & j).

package main

import &quot;fmt&quot;

func main() {
array := []int{45, 17, 43, 67, 21, 4, 97, 44, 54, 98, 665}
fmt.Println(&quot;initial array:&quot;, array)
loop_iteration := len(array)
if len(array)%2 == 0 {
	loop_iteration = (len(array) / 2) - 1
  } else {
	loop_iteration = int(len(array) / 2)  //This will give the lower integer value of that float number.
    }
for i := 0; i &lt;= loop_iteration; i++ {
	array[i], array[(len(array)-1)-i] = array[(len(array)-1)-i], array[i]
    }
fmt.Println(&quot;reverse array:&quot;, array)
}

答案16

得分: 0

package main

import (
	"fmt"
)

func main() {
	arr := []int{1, 2, 3, 4, 5}
	fmt.Println(reverseArray(arr))
}

func reverseArray(arr []int) []int {
	reversed := make([]int, len(arr))
	j := 0
	for i := len(arr) - 1; i >= 0; i-- {
		reversed[j] = arr[i]
		j++
	}
	return reversed
}
package main

import (
	"fmt"
)

func main() {
	arr := []int{1, 2, 3, 4, 5}
	fmt.Println(reverseArray(arr))
}

func reverseArray(arr []int) []int {
	reversed := make([]int, len(arr))
	j := 0
	for i := len(arr) - 1; i >= 0; i-- {
		reversed[j] = arr[i]
		j++
	}
	return reversed
}

这是一个使用Go语言编写的程序,它将一个整数数组反转并返回反转后的数组。在主函数中,创建了一个包含1、2、3、4、5的整数数组arr,并调用reverseArray函数对其进行反转。reverseArray函数使用一个新的数组reversed来存储反转后的结果,然后通过遍历原始数组arr,将元素从后往前依次放入reversed数组中。最后,返回反转后的数组reversed。程序输出结果为[5 4 3 2 1]。

英文:

https://go.dev/play/p/bVp0x7v6Kbs

package main

import (
	&quot;fmt&quot;
)

func main() {
	arr := []int{1, 2, 3, 4, 5}
	fmt.Println(reverseArray(arr))
}

func reverseArray(arr []int) []int {
	reversed := make([]int, len(arr))
	j := 0
	for i := len(arr) - 1; i &gt;= 0; i-- {
		reversed[j] = arr[i]
		j++
	}
	return reversed
}

答案17

得分: 0

使用泛型,您可以反转任何类型的数组

func reverseArray[T any](arr []T) []T {
	result := make([]T, len(arr))
	length := len(arr)
	for index := range arr {
		result[(length-1)-index] = arr[index]
	}
	return result
}

使用泛型,您可以反转任何类型的数组。这段代码定义了一个名为reverseArray的函数,它接受一个类型为T的切片arr作为参数,并返回一个类型为T的切片。函数通过创建一个与输入切片相同长度的切片result来存储结果。然后,它使用一个循环遍历输入切片,并将每个元素从末尾开始逆序存储到result切片中。最后,函数返回逆序后的切片result

英文:

Using generic so you can reverse any type arrays

func reverseArray[T any](arr []T) []T {
	result := make([]T, len(arr))
	length := len(arr)
	for index := range arr {
		result[(length-1)-index] = arr[index]
	}
	return result
}

答案18

得分: -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)
}

希望对你有帮助!

英文:

Here is my solution.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

package main

import (
	&quot;fmt&quot;
)

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&gt;=0 ; i-- {
		reverseNumbers[j]=numbers[i]
		j++	
	}
	fmt.Println(reverseNumbers)
}

<!-- end snippet -->

答案19

得分: -2

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

func reverse_array(array []string) []string {
	lenx := len(array) // lenx保存原始数组的长度
	reversed_array := make([]string, lenx) // 创建一个长度为lenx的新数组的切片
	
	for i := 0; i < lenx; i++ {
		j := lenx - (i + 1) // j初始值为(lenx - 1),随着i从0增加到(lenx - 1)递减到0
		reversed_array[i] = array[j]
	}
	
	return reversed_array
}

你可以在go playground上尝试这个解决方案 the go playground

package main

import "fmt"

func main() {
    array := []string{"a", "b", "c", "d"}
	
	fmt.Println(reverse_array(array)) // 输出 [d c b a]
}
英文:

Here is my solution to reversing an array:

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 &lt; 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
}

You can try this solution on the go playground the go playground

package main

import &quot;fmt&quot;

func main() {
    array := []string{&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;}
	
	fmt.Println(reverse_array(array)) // prints [d c b a]
}

答案20

得分: -3

不要反转它,保持现在的状态,然后只是反向迭代它。

英文:

Do not reverse it, leave it as now and then just iterate it backwards.

huangapple
  • 本文由 发表于 2013年10月8日 13:02:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/19239449.html
匿名

发表评论

匿名网友

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

确定