对数器-概念应用-选择排序的对数器

  当你没有大量测试数据但是又向测试你写的算法是否正确时,我想对数器可以帮你解决这个问题。

  选择排序算法的对数器的实现很简单。

  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];
            }
        }
    }

 

  不同的算法使用的对数器是不同的。

 

posted @ 2020-04-24 16:55  葡萄籽pp  阅读(188)  评论(0编辑  收藏  举报