猿问

这是一个合理且惯用的 GoLang 循环移位实现吗?

任何人都可以评论这是否是在 Go中实现整数数组循环移位的合理且惯用的方法?(我故意选择不使用按位运算。)


如何改进?


package main


import "fmt"


func main() {

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

    fmt.Println(a)

    rotateR(a, 5)

    fmt.Println(a)

    rotateL(a, 5)

    fmt.Println(a)

}


func rotateL(a []int, i int) {

    for count := 1; count <= i; count++ {

        tmp := a[0]

        for n := 1;n < len(a);n++ {

            a[n-1] = a[n]

        }

        a[len(a)-1] = tmp

    }

}


func rotateR(a []int, i int) {

    for count := 1; count <= i; count++ {

        tmp := a[len(a)-1]

        for n := len(a)-2;n >=0 ;n-- {

            a[n+1] = a[n]

        }

        a[0] = tmp

    }

}


红糖糍粑
浏览 253回答 3
3回答

慕田峪4524236

一次旋转切片一个位置,并重复以获得所需的总旋转量意味着需要的时间与旋转距离×切片长度成正比。通过将每个元素直接移动到其最终位置,您可以按与切片长度成比例的时间进行此操作。这段代码比你所拥有的要复杂一些,你需要一个 GCD 函数来确定通过切片的次数:func gcd(a, b int) int {&nbsp; &nbsp; for b != 0 {&nbsp; &nbsp; &nbsp; &nbsp; a, b = b, a % b&nbsp; &nbsp; }&nbsp; &nbsp; return a}func rotateL(a []int, i int) {&nbsp; &nbsp; // Ensure the shift amount is less than the length of the array,&nbsp; &nbsp; // and that it is positive.&nbsp; &nbsp; i = i % len(a)&nbsp; &nbsp; if i < 0 {&nbsp; &nbsp; &nbsp; &nbsp; i += len(a)&nbsp; &nbsp; }&nbsp; &nbsp; for c := 0; c < gcd(i, len(a)); c++ {&nbsp; &nbsp; &nbsp; &nbsp; t := a[c]&nbsp; &nbsp; &nbsp; &nbsp; j := c&nbsp; &nbsp; &nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k := j + i&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // loop around if we go past the end of the slice&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if k >= len(a) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k -= len(a)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // end when we get to where we started&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if k == c {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // move the element directly into its final position&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a[j] = a[k]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; j = k&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; a[j] = t&nbsp; &nbsp; }}旋转大小的片升权由p位置相当于旋转它留下由升- p位置,这样你就可以简化您的rotateR使用功能rotateL:func rotateR(a []int, i int) {&nbsp; &nbsp; rotateL(a, len(a) - i)}

胡子哥哥

您的代码适合就地修改。不明白你所说的按位运算是什么意思。也许这package main&nbsp; &nbsp; import "fmt"&nbsp; &nbsp; func main() {&nbsp; &nbsp; &nbsp; &nbsp; a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(a)&nbsp; &nbsp; &nbsp; &nbsp; rotateR(&a, 4)&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(a)&nbsp; &nbsp; &nbsp; &nbsp; rotateL(&a, 4)&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(a)&nbsp; &nbsp; }&nbsp; &nbsp; func rotateL(a *[]int, i int) {&nbsp; &nbsp; &nbsp; &nbsp; x, b := (*a)[:i], (*a)[i:]&nbsp; &nbsp; &nbsp; &nbsp; *a = append(b, x...)&nbsp; &nbsp; }&nbsp; &nbsp; func rotateR(a *[]int, i int) {&nbsp; &nbsp; &nbsp; &nbsp; x, b := (*a)[:(len(*a)-i)], (*a)[(len(*a)-i):]&nbsp; &nbsp; &nbsp; &nbsp; *a = append(b, x...)&nbsp; &nbsp; }代码有效https://play.golang.org/p/0VtiRFQVl7这在 Go 词汇中称为重新切片。权衡是在您的代码段中处理和循环与在此动态分配。这是您的选择,但在将 10000 个元素阵列移动一个位置的情况下,重新切片看起来便宜得多。

幕布斯6054654

我喜欢 Uvelichitel 解决方案,但如果您想要 O(n) 复杂度的模算术package mainfunc main(){&nbsp; &nbsp;s := []string{"1", "2", "3"}&nbsp; &nbsp;rot := 5&nbsp; &nbsp;fmt.Println("Before RotL", s)&nbsp; &nbsp;fmt.Println("After RotL", rotL(rot, s))&nbsp; &nbsp;fmt.Println("Before RotR", s)&nbsp; &nbsp;fmt.Println("After RotR", rotR(rot,s))}func rotL(m int, arr []string) []string{&nbsp; &nbsp; &nbsp;newArr := make([]string, len(arr))&nbsp; &nbsp; &nbsp;for i, k := range arr{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;newPos := (((i - m) % len(arr)) + len(arr)) % len(arr)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;newArr[newPos] = k&nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp;return newArr}func rotR(m int, arr []string) []string{&nbsp; &nbsp; &nbsp;newArr := make([]string, len(arr))&nbsp; &nbsp; &nbsp;for i, k := range arr{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;newPos := (i + m) % len(arr)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;newArr[newPos] = k&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; return newArr}
随时随地看视频慕课网APP

相关分类

Go
我要回答