对数器的适用场景
拿到一个算法题,做出来了,但找不到在线测试,无法验证代码是否正确,可以自己编写对数器来验证。
对数器的原理
为了验证算法代码(一般为优化解)的正确性,先写出该算法的暴力解,再生成若干随机的输入值(一般来说是数组,字符串等),若优化解和暴力解输出的结果均相同,说明优化解正确。
代码
这里以插入排序为例,我们需要编写对数器来验证插入排序的正确性。这里我们用冒泡排序作为排序的暴力解。具体思路是,生成若干随机数组,若插入排序与冒泡排序对这若干随机数组的排序后结果均相同,说明插入排序正确。
下面给出对数器java代码。
public class Validator {
public static void main(String[] args) {
int N = 200; //限制随机数组的最大长度
int testtimes = 5000; //验证5000次
int v = 1000; //限制数组的值在1-1000等概率
System.out.println("测试开始");
for (int i = 0; i < testtimes; i++) {
int n = (int)(Math.random() * N); //数组的随机长度为0 ~ n-1
int[] arr = randomArray(n, v);
int[] arr1 = copyArray(arr);
int[] arr2 = copyArray(arr);
insert(arr1);
bubble(arr2);
if (!sameArray(arr1, arr2)) {
System.out.println("出错了");
}
}
System.out.println("测试结束");
}
public static int[] randomArray(int n, int v) {
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = (int)(Math.random() * v) + 1;
}
return arr;
}
public static int[] copyArray(int[] arr) {
int[] copyArr = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
copyArr[i] = arr[i];
}
return copyArr;
}
public static boolean sameArray(int[] arr1, int[] arr2) {
int n = arr1.length;
for (int i = 0; i < n; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
public static void insert(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 1; i < arr.length; i++) {
for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
swap(arr, j, j - 1);
}
}
}
public static void bubble(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = arr.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j+1);
}
}
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
总结
任何题型都可以自己用对数器验证,但需要熟练写出暴力解(一般为递归)。