当你没有大量测试数据但是又向测试你写的算法是否正确时,我想对数器可以帮你解决这个问题。
选择排序算法的对数器的实现很简单。
1. 首先,你写好了一个选择排序的算法 A。
2. 同时,你有一个正确的实现排序的算法 B。(B 可以是任何算法,暴力的或者系统提供的,只要能保证正确就行)
3. 实现一个随机样本产生器。(在这里,就是产生一个长度随机,数值随机的数组)
4. 用 算法 A 和算法 B 跑相同的随机样本。看看得到的结果是否相同。
5. 如果有一个随机样本使得对比结果不一致,打印样本进行人工干预,改正算法 A。(或者有时是 算法 B)
6. 当样本数量很多时,比对测试依旧时正确,可以确定算法 A 已经正确。
对数器:
public static void logarithm() { int testTimes = 5000;// 测试次数 int maxSize = 100;// 数组最大长度 int maxValue = 100;// 数组中的数值,区间为 (-100,100] boolean succeed = true;// 记录测试是否成功 // 反复测试 testTimes 次 for (int i = 0; i < testTimes; i++) { // 生成随机数组 int[] arr1 = generateRandomArray(maxSize, maxValue); //拷贝 随机数组,数组 arr2 与 数组 arr1 元素完全相同,但是首地址不同 // 所以切记不可简单的赋值 , int[] arr2 = arr1 是错误的。 int[] arr2 = copyArray(arr1); selectSort(arr1); //选择排序方法 Arrays.sort(arr2); //系统提供的排序方法。 // 如果排序后,得到的数组不相等,说明本轮测试错误 if (!isEqual(arr1, arr2)) { succeed = false; printArray(arr1); printArray(arr2); break; } } System.out.println(succeed? "正确":"不正确"); }
产生随机数组方法:generateRandomArray
/** * 生成一个随机的数组 * @param maxSize 数组最大的长度 * @param maxNum 数组中最大的值 * @return */ public static int[] generateRandomArray(int maxSize, int maxValue) { // Math.random() -> [0,1) double // Math.random() * A -> [0,A) -> int // (int)(Math.random() * A) -> [0,A-1] int int len = (int) ((maxSize + 1) * Math.random()); int[] arr = new int[len]; for (int i = 0; i < len; i++) { // [0,A]-[0,A-1] arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); } return arr; }
数组拷贝方法:copyArray
/** * 将数组进行拷贝,值与传进来的数组相同,但是数组首地址不同 * @param arr * @return */ public static int[] copyArray(int[] arr) { if (arr == null) return null; int len = arr.length; int[] res = new int[len]; for (int i = 0; i < len; i++) { res[i] = arr[i]; } return res; }
比较数组元素是否相等:isEqual
/** * 比较两个数组中的元素是否完全相等 * @param arr1 * @param arr2 * @return */ public static boolean isEqual(int[] arr1, int[] arr2) { if (arr1.length != arr2.length) return false; boolean flag = true; for (int i = 0; i < arr1.length; i++) { if (arr1[i] != arr2[i]) { flag = false; break; } } return flag; }
打印数组:printArray
/** * 打印数组中所有的元素 * @param arr */ public static void printArray(int[] arr) { for (int cur : arr) System.out.print(cur + " "); System.out.println(); }
如果你没有写好选择排序的算法,不妨使用下面这个
public static void selectSort(int[] arr) { // 得到数组的长度 int len = arr.length; // 未排序数组从 i 到 len-1 for (int i = 0; i < len; i++) { // min 记录未排序数组最小值的下标 int min = i; // 遍历完整个未排序数组,得到最小值小标,将其与该未排序数组的第一个元素交换 for (int j = i + 1; j < len; j++) { if (arr[j] < arr[min]) min = j; } if (min > i) { arr[i] = arr[i] + arr[min]; arr[min] = arr[i] - arr[min]; arr[i] = arr[i] - arr[min]; } } }
不同的算法使用的对数器是不同的。