使用for循环翻转切片时出现逻辑错误。

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

Flipping a slice with a for loop logic error

问题

所以我正在尝试编写一个方法,它接受两个切片,翻转它们,并将它们互换。

例如:

s1 = {1,2,3,4,5}

s2 = {6,7,8,9,10}

应该返回:

s1 = {10,9,8,7,6}

s2 = {5,4,3,2,1}

以下是我的代码:

  1. package main
  2. import(
  3. "fmt"
  4. )
  5. func main(){
  6. f:= [5]int{1,2,3,4,5}
  7. h:= [5]int{6,7,8,9,10}
  8. var sliceF []int = f[0:5]
  9. var sliceH []int = h[0:5]
  10. fmt.Println(reverseReverse(sliceF,sliceH))
  11. }
  12. func reverseReverse(first []int, second []int) ([]int, []int){
  13. //创建临时数组以保存交换前的遍历数组
  14. var tempArr1 []int = first
  15. var tempArr2 []int = second
  16. //计数用于在循环中正确顺序地计数临时数组
  17. var count int= 0
  18. //遍历第一个数组,并将从末尾开始的值设置为临时数组的值
  19. //临时数组从左到右递增
  20. for i :=len(first)-1; i>=0;i--{
  21. tempArr1[count] = first[i]
  22. fmt.Println(i)
  23. count++
  24. }
  25. count =0
  26. //对第二个数组执行相同的操作
  27. for i :=len(second)-1; i>=0;i--{
  28. tempArr2[count] = second[i]
  29. count++
  30. }
  31. //尝试将参数数组的值替换为临时数组的值
  32. first=tempArr2
  33. second = tempArr1
  34. //返回数组
  35. return first,second
  36. }

运行后的输出如下:

4

3

2

1

0

[10 9 8 9 10]

[5 4 3 4 5]

*注意,我在for循环中包含了一个打印语句,以检查索引是否正确递减。

我知道有更好的方法来实现这个,但为了证明概念,我想使用for循环。

任何帮助都将不胜感激。我刚开始学习Go语言,往往会带有Java的习惯,所以我认为我的问题与此有关。

英文:

So I am trying to write a method that takes two slices, flips both of them and then gives them to each other.

Ex.

s1 = {1,2,3,4,5}

s2 = {6,7,8,9,10}

Should return:

s1 = {10,9,8,7,6}

s2 = {5,4,3,2,1}

Here is my code:

  1. package main
  2. import(
  3. "fmt"
  4. )
  5. func main(){
  6. f:= [5]int{1,2,3,4,5}
  7. h:= [5]int{6,7,8,9,10}
  8. var sliceF []int = f[0:5]
  9. var sliceH []int = h[0:5]
  10. fmt.Println(reverseReverse(sliceF,sliceH))
  11. }
  12. func reverseReverse(first []int, second []int) ([]int, []int){
  13. //creating temp arrays to hold the traversed arrays before swapping.
  14. var tempArr1 []int = first
  15. var tempArr2 []int = second
  16. //count is used for counting up the tempArrays in the correct order in the For loops
  17. var count int= 0
  18. //goes through the first array and sets the values starting from the end equal to the temp array
  19. //which increases normally from left to right.
  20. for i :=len(first)-1; i>=0;i--{
  21. tempArr1[count] = first[i]
  22. fmt.Println(i)
  23. count++
  24. }
  25. count =0
  26. //same as first for loop just on the second array
  27. for i :=len(second)-1; i>=0;i--{
  28. tempArr2[count] = second[i]
  29. count++
  30. }
  31. //trying to replace the values of the param arrays to be equal to the temp arrays
  32. first=tempArr2
  33. second = tempArr1
  34. //returning the arrays
  35. return first,second
  36. }

When run here is the output:

4

3

2

1

0

[10 9 8 9 10]

[5 4 3 4 5]

*Not I included a print statement in the for loop to check if the index is decreasing properly.

I understand there are better ways to do this but for proof of concept I want to use a for loop.

Any help appreciated. I am new to go and tend to have java habits so I assume somehow my problem is related to that.

答案1

得分: 2

这可以通过意识到实际上没有必要交换单个元素来简化。相反,反转每个数组并交换它们的顺序。这样更简单!

  1. func reverseReverse(a, b []int) ([]int, []int) {
  2. return reverse(b), reverse(a)
  3. }
  4. func reverse(a []int) []int {
  5. end := len(a) - 1
  6. // 为复制而分配一个相同长度的新数组切片。
  7. ret := make([]int, len(a))
  8. // 将a的每个元素反向复制到ret中。
  9. for i := range a {
  10. ret[end-i] = a[i]
  11. }
  12. return ret
  13. }

有了这个启示,就没有太大必要使用非常专门的reverseReverse函数了。自己交换顺序吧。

  1. fmt.Println(reverse(sliceH), reverse(sliceF))

请注意,如果你只想获取数组的一个切片,只需写sliceH []int := h[:],而不需要指定起始和结束位置。起始位置默认为0,结束位置默认为数组的末尾。还要注意,不需要声明类型,:=会为你处理。

更好的是,你可以直接声明和初始化它们。

  1. sliceF := []int{1, 2, 3, 4, 5}
  2. sliceH := []int{6, 7, 8, 9, 10}
英文:

This can be done much simpler by realizing there's no need to actually swap the individual elements. Instead, reverse each array and swap their order. Much simpler!

  1. func reverseReverse( a, b []int ) ([]int, []int) {
  2. return reverse(b), reverse(a)
  3. }
  4. func reverse( a []int ) []int {
  5. end := len(a) - 1
  6. // Allocate a new array slice of the same length to copy to.
  7. ret := make( []int, len(a) )
  8. // Copy each element of a into ret, reversed.
  9. for i := range a {
  10. ret[end-i] = a[i]
  11. }
  12. return ret
  13. }

With that revelation, there's little need for the very specialized reverseReverse function. Swap the order yourself.

  1. fmt.Println(reverse(sliceH), reverse(sliceF))

Note that if you just want to take a slice of an array, it's sufficient to write sliceH []int := h[:] without specifying the start and end. The start is assumed to be 0 and the end is the end. Also note there's no need to declare the type, := takes care of that for you.

Even better, you can declare and initialize them directly.

  1. sliceF:= []int{1,2,3,4,5}
  2. sliceH:= []int{6,7,8,9,10}

答案2

得分: 1

简短回答:

这行代码在逻辑上等同于:

详细回答:

x := [5]int{}x := []int{} 实际上是两个非常不同的赋值方式。在第一种情况下,x 实际上是一个静态数组。而在第二种情况下,x 是一个切片,它实际上是一个具有长度、容量和指向底层数组的指针的数据结构。因此,var tempArr1 []int = first 的意思是将 first 的底层数组的指针复制到 tempArr1 中,所以对 first[i] 的任何修改都会反映在 tempArr1 中,反之亦然。

英文:

Short answer:

This line is logically identical to:

Detailed answer:

x := [5]int{} and x := []int{} are in fact two very different assignments. In the first case x is actually a static array. In the second case x is a slice which is in fact a data structure which has a length, capacity and a pointer to the underlying array. Therefore, var tempArr1 []int = first means copy the pointer to the underlying array of first into the tempArr1, so any modification to first[i] will be reflected in tempArr1 and vice versa

答案3

得分: 1

例如,

  1. package main
  2. import "fmt"
  3. func reverse(s []int) []int {
  4. for i := 0; i < len(s)/2; i++ {
  5. s[i], s[len(s)-1-i] = s[len(s)-1-i], s[i]
  6. }
  7. return s
  8. }
  9. func main() {
  10. s1, s2 := []int{1, 2, 3, 4, 5}, []int{6, 7, 8, 9, 10}
  11. fmt.Println(s1, s2)
  12. s1, s2 = reverse(s2), reverse(s1)
  13. fmt.Println(s1, s2)
  14. }

输出:

  1. [1 2 3 4 5] [6 7 8 9 10]
  2. [10 9 8 7 6] [5 4 3 2 1]
英文:

For example,

  1. package main
  2. import &quot;fmt&quot;
  3. func reverse(s []int) []int {
  4. for i := 0; i &lt; len(s)/2; i++ {
  5. s[i], s[len(s)-1-i] = s[len(s)-1-i], s[i]
  6. }
  7. return s
  8. }
  9. func main() {
  10. s1, s2 := []int{1, 2, 3, 4, 5}, []int{6, 7, 8, 9, 10}
  11. fmt.Println(s1, s2)
  12. s1, s2 = reverse(s2), reverse(s1)
  13. fmt.Println(s1, s2)
  14. }

Output:

  1. [1 2 3 4 5] [6 7 8 9 10]
  2. [10 9 8 7 6] [5 4 3 2 1]

huangapple
  • 本文由 发表于 2017年6月15日 05:24:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/44554951.html
匿名

发表评论

匿名网友

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

确定