C / C ++ - 在不使用内置函数的情况下旋转数组的有效方法(作业)

时间:2015-11-22 22:15:12

标签: c++ arrays algorithm performance

任务是向左旋转或向右旋转一个数组的子阵列给定次数。

让我以一个例子来解释:

  • 让数据成为一个数组。

data = {0,1,2,3,4,5,6,7,8,9};

  • 子数组由参数begin和end确定。

如果begin = 3且end = 7,则子阵列为{0,1,2, 3,4,5,6,7, 8,9};

如果begin = 7且end = 3,则子阵列为{ 0,1,2,3 ,4,5,6, 7,8,9 } ;

  • 让它旋转两次

如果begin = 3且end = 7,则结果为{0,1,2, 6,7,3,4,5, 8,9};

如果begin = 7且end = 3,则结果为{ 8,9,0,1,,4,5,6, 2,3,7 };

我编写了执行此任务的代码,但速度很慢。 有人能给我一个提示如何更快地提示吗? 重要提示:我不允许使用除数据,子程序和内置函数之外的其他数组。

#include <iostream>
using namespace std;

int main(){

    int dataLength;

    cin >> dataLength;

    int data [ dataLength ];

    for (int i = 0; i < dataLength; i++){
        cin >> data [ i ];
    }


    int begin;
    int end;
    int rotation;
    int forLoopLength;
    int tempBefore;
    int tempAfter;

    cin >> begin;
    cin >> end;
    cin >> rotation;

    if (end > begin)
       forLoopLength = (end - begin) + 1;
    else
       forLoopLength = (end - begin) + 1 + dataLength;

    if (rotation < 0) 
       rotation = forLoopLength + (rotation % forLoopLength);
    else
        rotation = rotation % forLoopLength;

    for (int i = 0; i < rotation; i++) {

        tempBefore = data [ end ];

        for (int i = 0; i < forLoopLength; i++) {
            tempAfter = data [ (begin + i) % dataLength ];
            data [ (begin + i) % dataLength ] = tempBefore;
            tempBefore = tempAfter;
        }
    }

    for (int i = 0; i < dataLength; i ++ ) {
        cout << data [ i ] << " ";
    }

    return 0;
}

2 个答案:

答案 0 :(得分:8)

这是一个诀窍。如果在课堂上没有提到这个伎俩,你就可以把它作为家庭作业,这很奇怪。总之...

旋转由M留下的N个元素序列:

  • 颠倒整个序列
  • 反转最后的M个元素
  • 反转第一个N-M元素

完成

e.g。离开2: 1234567 - &GT; 7654321 - &GT; 7654312 - &GT; 3456712

答案 1 :(得分:2)

这是我的代码,它完全是n次读取和n次写入,其中n是子阵列大小。

#include<iostream>

int arr[]= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// replacing 'addr( pos, from, size )' with just 'pos' mean rotation the whole array
int addr( int ptr, int from, int size)
{
  return (ptr + from ) % size;
}

void rotate( int* arr, int shift, int from, int count, int size)
{
  int i;
  int pos= 0;
  int cycle= 0;
  int c= 0;
  int c_old= 0;
  // exactly count steps
  for ( i=0; i< count; i++ ){
    // rotation of arrays part is essentially a permutation.
    // every permutation can be decomposed on cycles
    // here cycle processing begins
    c= arr[ addr( pos, from, size )  ];
    while (1){
      // one step inside the cycle
      pos= (pos + shift) % count;
      if ( pos == cycle )
        break;
      c_old= c;
      c= arr[ addr( pos, from, size )  ];
      arr[ addr( pos, from, size ) ]= c_old;
      i++;
    }
    // here cycle processing ends
    arr[ addr( pos, from, size ) ]= c;
    pos=   (pos   + 1) % count;
    cycle= (cycle + 1) % count;
  }
}

int main()
{
  rotate( arr, 4, 6, 6, 11 );
  int i;
  for ( i=0; i<11; i++){
    std::cout << arr[i] << " ";
  }
  std::cout << std::endl;
  return 0;
}