2017-06-14 45 views
2

所以我想寫一個需要兩個切片的方法,翻轉他們兩個,然後將它們給對方。用for循環邏輯錯誤翻轉切片

Ex。

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

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

應返回:

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

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

這是我的代碼:

package main 
import(
    "fmt" 
) 

func main(){ 
    f:= [5]int{1,2,3,4,5} 
    h:= [5]int{6,7,8,9,10} 
    var sliceF []int = f[0:5] 
    var sliceH []int = h[0:5] 

    fmt.Println(reverseReverse(sliceF,sliceH)) 

} 
func reverseReverse(first []int, second []int) ([]int, []int){ 
    //creating temp arrays to hold the traversed arrays before swapping. 
    var tempArr1 []int = first 
    var tempArr2 []int = second 
    //count is used for counting up the tempArrays in the correct order in the For loops 
    var count int= 0 
    //goes through the first array and sets the values starting from the end equal to the temp array 
    //which increases normally from left to right. 
    for i :=len(first)-1; i>=0;i--{ 
     tempArr1[count] = first[i] 
     fmt.Println(i) 
     count++ 
    } 
    count =0 
    //same as first for loop just on the second array 
    for i :=len(second)-1; i>=0;i--{ 
     tempArr2[count] = second[i] 
     count++ 
    } 
    //trying to replace the values of the param arrays to be equal to the temp arrays 
    first=tempArr2 
    second = tempArr1 
    //returning the arrays 
    return first,second 
} 

當此處運行是輸出:

[10 9 8 9 10]

[ 5 4 3 4 5]

*我沒有在for循環中包含print語句來檢查索引是否正常遞減。

我知道有更好的方法來做到這一點,但爲了證明概念,我想使用for循環。

任何幫助表示讚賞。我是新來的,並傾向於有Java習慣,所以我假設我的問題與此有關。

回答

2

這是可以做到更簡單沒有必要以實際交換個人元素。相反,反轉每個數組並交換它們的順序。簡單得多!

func reverseReverse(a, b []int) ([]int, []int) { 
    return reverse(b), reverse(a) 
} 

func reverse(a []int) []int { 
    end := len(a) - 1 

    // Allocate a new array slice of the same length to copy to. 
    ret := make([]int, len(a)) 

    // Copy each element of a into ret, reversed. 
    for i := range a { 
     ret[end-i] = a[i] 
    } 

    return ret 
} 

有了這個啓示,幾乎沒有必要使用非常專業的reverseReverse函數。自己交換訂單。

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

需要注意的是,如果你只是想利用數組的一個切片,它足以寫sliceH []int := h[:]沒有指定的起點和終點。開始被假定爲0並且結束是結束。另外請注意,不需要聲明該類型,:=爲您處理。

更妙的是,你可以聲明並直接初始化。

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

得到它固定感謝您的幫助!我需要給切片一個長度,不知道如何,直到我看到你的製作方法,並查找它! – HoldenMalinchock

+0

如果您不介意就地倒轉,則可以通過使用多變量賦值語法縮短。也減少了內存佔用。 https://play.golang.org/p/cCXEuQ3Nr5 – Kaedys

+0

@Kaedys是,peterSO的回答演示倒車到位。有了好的陣列複製功能,就地版本將是首選。 – Schwern

1

短的答案:

tempArr1[count] = first[i]

這條線是邏輯上等同於:

first[count] = first[i]

詳細答案:

x := [5]int{}x := []int{}實際上是兩個非常不同的作業。在第一種情況下,x實際上是一個靜態數組。在第二種情況下,x切片,其實際上是具有長度,容量和指向底層陣列的指針的數據結構。因此,var tempArr1 []int = first手段指針複製到的first基礎數組到tempArr1,所以任何修改first[i]將反映在tempArr1和實現反之亦然

+0

唉唉好了,然後來解決,我將放棄等號部分,只是聲明瞭嗎? – HoldenMalinchock

+0

但我碰到的問題是,我希望它是我不知道片進入的大小。因此,當我把=第一部分,我該怎麼取而代之的是,因爲當我剛落,我得到它一個數組越界異常。 – HoldenMalinchock

+0

我已經修好了,感謝您的幫助! – HoldenMalinchock

1

例如,

package main 

import "fmt" 

func reverse(s []int) []int { 
    for i := 0; i < len(s)/2; i++ { 
     s[i], s[len(s)-1-i] = s[len(s)-1-i], s[i] 
    } 
    return s 
} 

func main() { 
    s1, s2 := []int{1, 2, 3, 4, 5}, []int{6, 7, 8, 9, 10} 
    fmt.Println(s1, s2) 
    s1, s2 = reverse(s2), reverse(s1) 
    fmt.Println(s1, s2) 
} 

輸出:

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

注意,雖然'反向()'返回一個切片,就好像它是一個副本,它反轉原始數組。這是誤導。 '反向(S1);反向(S2); fmt.Println(s2,s1)'也同樣適用。 – Schwern