右阵列旋转的杂耍算法

时间:2020-03-25 17:56:43

标签: c++ arrays algorithm data-structures

最近,我使用杂耍算法了解了线性时间内的数组旋转。这是有关数组向左旋转的代码段。

void ArrayRotate (int A[], int n, int k)
{
  int d=-1,i,temp,j;
  for(i=0;i<gcd(n,k);i++)
  {
    j=i;
    temp=A[i];
    while(1)
    {
      d=(j+k)%n;
      if(d==i)
        break;
      A[j]=A[d];
      j=d;
    }
    A[j]=temp;
  }
}

但是现在我被困在如何使用这种杂耍算法向正确方向旋转数组上。

1,2,3,4,5  (given array) 
5,1,2,3,4   (after 1 right rotation)

(我已经使用蛮力法和逆向法解决了这个问题。)

2 个答案:

答案 0 :(得分:1)

  1. 如前所述,如果允许,您应该使用std :: rotate。
  2. 您的实现中有一个错误。这是一个固定的实现。
void ArrayRotate(int A[], int n, int k) {
    int d = -1, i, temp, j;
    int g = gcd(n, k);
    for (i = 0; i < g; ++i) {
        j = i;
        temp = A[i];
        while (true) {
            d = (j + k) % n;
            if (d == i) {
                break;
            }
            A[j] = A[d];
            j = d;
        }
        A[j] = temp;
    }
 }

还请注意,我在循环条件外进行了gcd计算。从技术上讲,它不会影响复杂性,但是只计算一次gcd就足够了。

要向右旋转数组k次,只需向左旋转n - k次。

void ArrayRotateRight(int A[], int n, int k) {
    ArrayRotate(A, n, n - k);
}

或将第8行更改为d = (j - k + n) % n;

答案 1 :(得分:0)

不确定是作为智力活动还是针对生产代码,但是对于生产代码,请使用STL rotate算法:

#include<iostream>
#include<algorithm>

using namespace std;

void display(int* a, int length)
{
    for (int i = 0; i < length; ++i)
        cout << a[i] << " ";

    cout << endl;
}

int main()
{
    const int len = 5;

    int arr[] =  { 1,2,3,4,5 };

    display(arr, len);

    rotate(arr, arr + 1, arr + len); // arr + x means left by x

    display(arr, len);

    rotate(arr, arr + len - 1, arr + len); // arr + len - x means right by x 

    display(arr, len);
}