陣列元素迴圈右移問題

Amei1314發表於2016-11-16

一個陣列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

相關文章