/**
* Author: yiminghe
* Date: 2008-10-29
* Time: 22:55:06
*/
import java.util.Arrays;
/**
* 将数组的前K个数和后n-k个数交换位置
* 如 1,2,3,4,5,6
* k=4
* 得到
* 5,6 ,1,2,3,4
*/
public class SwapMore {
private static void swap(int[] array, int a1, int a2) {
int t = array[a1];
array[a1] = array[a2];
array[a2] = t;
}
/**
* 最笨的方法 循环移位
*
* @param array
* @param k
*/
public static void swaps(int[] array, int k) {
if (array.length <= k) return;
while (k > 0) {
int t = array[0];
for (int i = 0; i < array.length - 1; i++) {
array[i] = array[i + 1];
}
array[array.length - 1] = t;
k--;
}
}
private static void reverse(int[] array, int start, int end) {
while (start < end) {
swap(array, start, end);
start++;
end--;
}
}
/**
* 好点的方法:
* uv -> vu
* vu=((u_) (v_) ) _
* u_表示 u数组的倒序
*
* @param array
* @param k
*/
public static void swaps2(int[] array, int k) {
reverse(array, 0, k - 1);
reverse(array, k, array.length - 1);
reverse(array, 0, array.length - 1);
}
private static int gcd(int a1, int a2) {
if (a1 < a2) {
int t = a1;
a1 = a2;
a2 = t;
}
if (a1 % a2 == 0)
return a2;
return gcd(a2, a1 % a2);
}
/**
* 最好的方法 ,利用数学 。。。。
* 最大公因式
* 没必要全部当做一个环循环移位
* 有几个环 ,对每个环移位,直接移到位
* 环的个数等于 gcd(k, array.length - k)=gcd(k, array.length)
*
*
* @param array
* @param k
*/
public static void swaps3(int[] array, int k) {
int loop = gcd(k, array.length - k);
for (int i = 0; i < loop; i++) {
System.out.println(Arrays.toString(array));
int t = array[i];
int p = i;
int j = (i + k) % array.length;
while (i != j) {
array[p] = array[j];
p = j;
j = (p + k) % array.length;
System.out.println("---" + Arrays.toString(array));
}
array[p] = t;
}
}
public static void main(String[] ars) {
int[] a = {1, 2, 3, 4, 5, 6, 7};
swaps3(a, 3);
System.out.println(Arrays.toString(a));
}
}
附:辗转相除法证明:
z 是 a,b的约数
a/z==0 b/z==0
则 (a%b)/z ==0
则 a,b约数 与 a,a%b约数相同 (a>b)
若 a%b==0 则 b 就是 a,b 的最大公约数
则辗转相除法得证