在日常编程中,我们经常需要对数组进行打乱操作(类似洗牌),尤其在构建某些游戏、抽奖系统或测试数据生成时尤为常见(数字华容道)。本文将带你一步一步实现以下两个功能:
- 创建一个顺序填充的二维数组
- 打乱这个二维数组中的所有元素位置
一、创建二维数组 creatArrArr
/**
* 创建一个 row 行 col 列的二维整型数组,数组元素按从 1 开始递增填充
* @param row 行数
* @param col 列数
* @return 填充好的二维数组
*/
public static int[][] creatArrArr(int row, int col) {
// 创建指定行列的二维数组
int[][] arr = new int[row][col];
// 初始填充值,从 1 开始
int n = 1;
// 外层循环控制行
for (int i = 0; i < row; i++) {
// 内层循环控制列
for (int j = 0; j < col; j++) {
// 顺序填充值
arr[i][j] = n++;
}
}
return arr;
}
示例输出:
调用 creatArrArr(3, 4) 将返回如下二维数组:
1 2 3 4
5 6 7 8
9 10 11 12
二、打乱二维数组 disorganizeArr
为了打乱二维数组中所有的元素,我们采用遍历每个元素并与随机位置交换的方法。这样可以保证所有元素都有可能被打乱。
/**
* 打乱二维数组中所有元素的位置(乱序洗牌)
* @param arr 原始二维数组
* @return 打乱后的二维数组
*/
public static int[][] disorganizeArr(int[][] arr) {
// 注意:newArr 实际上引用的是原始数组 arr,并未真正新建新数组
int[][] newArr = arr;
// 遍历二维数组的每个元素
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
// 生成一个随机行索引
int randomN1 = (int)(Math.random() * arr.length);
// 注意此处避免越界:
// 随机列索引范围限定为随机行的实际长度(防止不规则二维数组越界)
int randomN2 = (int)(Math.random() * arr[randomN1].length);
// 交换当前元素与随机位置的元素
int temp = newArr[i][j];
newArr[i][j] = newArr[randomN1][randomN2];
newArr[randomN1][randomN2] = temp;
}
}
return newArr;
}
关键点解析:
- 第二个随机索引
randomN2的范围取决于randomN1指定的行长度,这是为了避免二维数组非规则(行长度不同)时出现越界。