在做游戏的时候碰到一个问题:从数组int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}中随机取16个不同的数,即对数组取一个随机排列,生成一个新的数组
方法一:开始想到的方法是从1-16中每次随机取出一个数,放到sourceArray 数组中去,同时将获得的随机数放到outArray 数组中,然后再随机取数,先与outArray 数组中进行一一比较,如果已经存在,重新随机取数。
该方法简单易懂,但时间复杂度与空间复杂度都比较大、、、
方法二:去网上搜索,知道这叫做洗牌算法,有多种方法实现。最终感觉这种方法简单易懂,计算量小。
方法是多次随机交换数组中的两个值,交换次数越多,越随机。
源代码:
public class RandomArray {
/**
* 类RandomArray,测试产生随机数组类
* @author 张世民
* 创建时间 2011-8-2
* */
public static void main(String[] args){
System.out.println("----------------");
//randomArray2(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
randomArray1();
}
public static void randomArray1(){
int time = 0;//计算循环次数
int[] sourceArray = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int[] outArray = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int i = 0;
while(i < 16){
int flag = 0;
int index = (int) (Math.random()*sourceArray.length + 1);
for(int j = 0; j < outArray.length; j ++){
time ++;
if(outArray[j] == index){
flag = 1;
break;
}
else flag = 0;
}
if(flag == 0){
sourceArray[i] = index;
outArray[i] = index;
i++;
System.out.println(index);
}
}
System.out.println(time);
}
public static void randomArray2(int[] sourceArray){
System.out.println("----------------");
int tmp = 0;
int p1, p2;
int cnt = 20;//随机交换次数,在合适范围内,值越大越随机
while(cnt > 0){
p1 = (int) (Math.random()*sourceArray.length);
p2 = (int) (Math.random()*sourceArray.length);
tmp = sourceArray[p1];
sourceArray[p1] = sourceArray[p2];
sourceArray[p2] = tmp;
cnt--;
}
for(int i = 0; i < 16; i++){
System.out.println(sourceArray[i]);
}
}
}
再碰到其他方法时再添加