算法-对数器模板-数组(Java)

本文记录了从左神的算法课中学到的对数器概念及其应用。对数器用于验证算法正确性,通过与已知正确但效率低的方法对比大量测试样本。以冒泡排序为例,介绍了如何使用对数器进行测试,包括方法A的实现、正确方法B的实现、随机样本生成和比较方法。
摘要由CSDN通过智能技术生成

最近在看左神的算法课,里面讲到了对数器,在此将其记录下来

对数器的概念

  1. 有一个你想要测试的方法A
  2. 实现一个绝对正确,但是时间复杂度不好的方法B
  3. 实现一个随机样本产生器
  4. 实现对比的方法
  5. 把方法A和方法B对比验证很多此来验证方法A是否正确
  6. 当样本数量很多时比对测试依然正确,可以确定方法a已经正确

对数器的使用

1、写一个需要测试的方法A,以冒泡排序为例

    /**
     * 去除低阶项,保留高阶项,去除高阶项的系数
     * 冒泡排序,时间复杂度=o(N^2)=N*(N-1)*...*1=aN^2+bN+1
     *
     * @param arr 待排的数组
     */
    private static void bubbleSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int end = arr.length - 1; end > 0; end--) {
            for (int i = 0; i < end; i++) {
                if (arr[i] > arr[i + 1]) {
                    swap(arr, i, i + 1);
                }
            }
        }
    }

    /**
     * 交换数组中i和j的位置
     *
     * @param arr 数组
     * @param i   i
     * @param j   j
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

2、实现一个绝对正确,但是时间复杂度不好的方法B

    /**
     * 2.实现一个绝对正确的方法
     *
     * @param arr
     */
    public static void rightMethod(int[] arr) {
        Arrays.sort(arr);//JDK自带方法
    }

3、实现一个随机样本产生器

    /**
     * 3.实现一个随机样本产生器
     * Math.random():返回double类型的[0,1)之间的数
     *
     * @param maxSize  数组的最大大小
     * @param maxValue 数组数值的最大值
     * @return 返回一个最大长度位maxSize,每一个位置在范围[-maxValue,maxValue]的数组
     */
    public static int[] generateRandomArray(int maxSize, int maxValue) {
        int[] arr = new int[(int) ((maxSize + 1) * Math.random())];//产生一个[0,maxSize]的数组
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
        }
        return arr;
    }

4、实现对比的方法

    /**
     * 数组比较
     *
     * @param arr1 数组1
     * @param arr2 数组2
     * @return true/false
     */
    public static boolean isEqual(int[] arr1, int[] arr2) {
        if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
            return false;
        }
        if (arr1 == null && arr2 == null) {
            return true;
        }
        if (arr1.length != arr2.length) {
            return false;
        }
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

测试

1、把以上模板方法整合成一个工具类

public class ArrayUtil {
    /**
     * 2.实现一个绝对正确的方法
     *
     * @param arr 随机生成的数组
     */
    public static void rightMethod(int[] arr) {
        Arrays.sort(arr);
    }

    /**
     * 3.实现一个随机样本产生器
     * Math.random():返回double类型的[0,1)之间的数
     *
     * @param maxSize  数组的最大大小
     * @param maxValue 数组数值的最大值
     * @return 返回一个最大长度位maxSize,每一个位置在范围[-maxValue,maxValue]的数组
     */
    public static int[] generateRandomArray(int maxSize, int maxValue) {
        int[] arr = new int[(int) ((maxSize + 1) * Math.random())];//产生一个[0,maxSize]的数组
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
        }
        return arr;
    }

    /**
     * 数组拷贝
     *
     * @param arr 待拷贝的数组
     * @return 新数组
     */
    public static int[] arrayCopy(int[] arr) {
        int[] newArr = new int[arr.length];
        System.arraycopy(arr, 0, newArr, 0, arr.length);
        return newArr;
    }

    /**
     * 数组比较
     *
     * @param arr1 数组1
     * @param arr2 数组2
     * @return true/false
     */
    public static boolean isEqual(int[] arr1, int[] arr2) {
        if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
            return false;
        }
        if (arr1 == null && arr2 == null) {
            return true;
        }
        if (arr1.length != arr2.length) {
            return false;
        }
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 打印排序结果
     * @param newArray 随机生成的数组
     * @param sortArray 排序后的数组
     * @param rightArray 正确结果
     */
    public static void printCompareResult(int[] newArray,int[] sortArray, int[] rightArray){
        System.out.println("生成结果="+Arrays.toString(newArray));
        System.out.println("排序结果="+Arrays.toString(sortArray));
        System.out.println("正确结果="+Arrays.toString(rightArray));
    }
}

2、测试

    public static void main(String[] args) {
        int maxTime = 50 * 10000;//测试次数
        int maxSize = 100;//数组最大大小
        int maxValue = 100;//数组子项最大值
        boolean isSucceed = true;//是否测试成功
        for (int i = 0; i < maxTime; i++) {
            int[] array1 = generateRandomArray(maxSize, maxValue);//随机生成的数组
            int[] array2 = arrayCopy(array1);//存放正确结果的数组
            int[] array3 = arrayCopy(array1);//待排序的数组
            bubbleSort(array3);
            rightMethod(array2);
            if (!isEqual(array3, array2)) {
                isSucceed = false;
                ArrayUtil.printCompareResult(array1,array3,array2);
                break;
            }
        }
        System.out.println(isSucceed ? "Nice!" : "Error!");
    }

验证正确:
在这里插入图片描述
验证失败:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值