数组元素循环右移问题


一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1……AN-1)变换为(AN-M …… AN-1 A0 A1……AN-M-1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法? 输入格式:每个输入包含一个测试用例,第1行输入N ( 1
<=N<=100)、M(M>=0);第2行输入N个整数,之间用空格分隔。 输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。 输入样例: 6 2 1 2 3 4 5 6 输出样例: 5 6 1 2 3 4

 

1. 就简单的暴力移动。

  

#include <stdio.h>
#include <stdlib.h>

void right_shift(int *data,int length,int offset);
void print_array(int *data,int length);

int main(){
  int number,move;
  int i;
  int* data;
  scanf("%d%d",&number,&move);
  data = (int *)malloc(sizeof(int)*number);
  for ( i = 0; i < number; i ++ ){
    scanf("%d",data + i);
  }
  right_shift(data,number,move % number);
  print_array(data,number);
  return 0;
}

void right_shift(int *data,int length,int offset){
  int index = length - offset;
  int shift;
  int temp,i,fix=index;
  while(index < length){
    temp = data[index];
    shift = index;
    i = fix;
    while( i-- ){
      data[shift] = data[shift - 1];
      shift --;
    }
    data[shift] = temp;
    index ++;
  }
}

void print_array(int *data,int length){
  int i;
  for ( i = 0; i < length - 1; i ++ ){
      printf("%d ",data[i]);
  }
  printf("%d\n",data[i]);
}

 

2. 暴力移动的代码优化

    上述代码的right_shift函数的可读性太差,我们将其拆分未两个函数,其中一个函数每次只向右边移动一次(right_shift_one),right_shift函数负责调用right_shift_one函数完成n次的移动。

#include <stdio.h>
#include <stdlib.h>

void right_shift_one(int *data,int length);
void right_shift_one(int *data,int length,int offset);
void print_array(int *data,int length);

int main(){
  int number,move;
  int i;
  int* data;
  scanf("%d%d",&number,&move);
  data = (int *)malloc(sizeof(int)*number);
  for ( i = 0; i < number; i ++ ){
    scanf("%d",data + i);
  }
  right_shift(data,number,move % number);
  print_array(data,number);
  return 0;
}

void right_shift_one(int *data,int length){
  int temp = data[length-1];
  while(--length){
    data[length] = data[length - 1];
  }
  data[length] = temp;
}

void right_shift(int *data,int length,int offset){
  while(offset--)
    right_shift_one(data,length);
}

void print_array(int *data,int length){
  int i;
  for ( i = 0; i < length - 1; i ++ ){
      printf("%d ",data[i]);
  }
  printf("%d\n",data[i]);
}

 

3. 巧妙的交换

  上述的暴力移动明显比较费时,下边通过三次交换就可以完成。

#include <stdio.h>
#include <stdlib.h>

void reverse(int *data,int start,int end);
void print_array(int *data,int length);

int main(){
  int number,move;
  int i;
  int* data;
  scanf("%d%d",&number,&move);
  data = (int *)malloc(sizeof(int)*number);
  for ( i = 0; i < number; i ++ ){
    scanf("%d",data + i);
  }
  move = move % number;
  reverse(data,0,number - move -1);
  reverse(data,number - move,number - 1);
  reverse(data,0,number - 1);
  print_array(data,number);
  return 0;
}

void reverse(int *data,int start,int end){
  int temp;
  for (;start < end; start ++,end --){
    temp = data[start];
    data[start] = data[end];
    data[end] = temp;
  }
}

void print_array(int *data,int length){
  int i;
  for ( i = 0; i < length - 1; i ++ ){
      printf("%d ",data[i]);
  }
  printf("%d\n",data[i]);
}

 

http://blog.csdn.net/u013802188/article/details/37599807

posted @ 2016-11-16 15:33  Amei1314  阅读(1091)  评论(0编辑  收藏  举报