2021 后端笔试准备 19 选择排序 与 对数器

什么是对数器?

对数器简单来说通过大样本量 和 一个绝对正确的算法 来验证我们的题目是否正确。

对数器复杂一点:
1.有一个你想要测的方法a;
2.实现一个绝对正确但是复杂度不好的方法b;
3.实现一个随机样本产生器;
4.实现对比算法a和b的方法;
5.把方法a和方法b比对多次来验证方法a是否正确;
6.如果有一个样本使得比对出错,打印样本分析是哪个方法出错;
7.当样本数量很多时比对测试依然正确,可以确定方法a已经正确。

总结
通过两种不同思路的解法,然后自己生成题目要求的随机数据(这个挺费功夫的),先用第一种不同思路,但是绝对正确的算法解决,然后再用你自己写的算法解决,然后对比答案。一般绝对正确的答案,往往是那种简单的容易想到的,但是时间复杂度很差,所以重点是在正确的随机输入如何生成,这个需要勤加练习。

为什么需要对数器?

  1. 锻炼代码能力,对数器的各种边界条件可能没比写算法差多少
  2. 网上有一部分的题目是没有测试用例的,如果知道对数器你就能自己去验证你的算法正确与否
  3. 控制样本量来对题目进行测试,比较容易的排查出错误
package class01;

import java.util.Arrays;
public class SelectionSort {

下面是选择排序的代码,这个之前的博客里面讲过,所以这里就不详细讲了,需要的可以看这里

    public static void selection(int[] arr){
        // 输入整数类型的列表
        if(arr == null || arr.length < 2){
            // 如果输入的数组为空或者小于 2就直接返回,为空和为1都不用排序是吧?
            return;
        }

        for(int i = 0; i < arr.length; i++) {
            //遍历数组中的每一个元素,申请一个变量记录最小的元素
            int minIdx = i;
            for(int j = i + 1; j < arr.length; j++){
                // 找到最小元素,交换
                minIdx = arr[i] < arr[minIdx] ? j : minIdx;
            }
            swap(arr, minIdx, i);
        }
    }

    public static void swap(int[] arr, int idxOne, int idxTwo){
        // 交换两个元素
        int temp = arr[idxOne];
        arr[idxOne] = arr[idxTwo];
        arr[idxTwo] = temp;
    }

下面是对数器
我们先通过main方法来看看对数器的主要思路:

我们总共有四个步骤:生成随机数,简单方法排序,自己的实现进行排序,最后对比两者答案。

生成随机数组,我们需要明确生成数组的每个元素的取值范围,这里使用maxValue来控制,100的意思是正100到-100。
生成随机数组的长度,这里是用 maxSize来进行控制,我们这里选择生成长度为100的数组。

然后我们通过 testTime和循环来控制我们测试的次数,每次测试生成新的数组,然后用两个不同的方法进行排序和校验,然后通过一个布尔变量来告知是对是错。当我们每次测试的时候要是有数组排序出错了,我们课可以将他打印出来,进行针对性的debug。我们也可以通过调整随机输入的规模来降低我们debug的难度。

    public static void main(String[] args) {
        int testTime = 500000; // 测试的次数
        int maxValue = 100; // 随机长度 0 ~ 100
        int maxSize = 100; // 随机值 -100 ~ 100
        boolean succeed = true;

        for(int i = 0; i < testTime; i++){
            int[] arr1 = generateRandomArray(maxSize, maxValue);// 生成一个随机数组
            int[] arr2 = copyArray(arr1); // 将原来生成的随机数组,进行拷贝,开辟新的内存空间

            selection(arr1); // 用你自己的方法进行排序
            comparator(arr2); // 用绝对不会错的方法进行排序
            if(!isEqual(arr1, arr2)){ // 对比两个答案
                succeed = false;
                printArray(arr1);
                printArray(arr2);
                break;// 有错就break
            }
        }
        System.out.println(succeed ? "Nice" : "Error");// 最后要是程序没有错就打印Nice,错了打印Error
    }
    // 随机数组生成
    public static int[] generateRandomArray(int maxSize, int maxValue){
        // Math.random() -> [0, 1) 所有小数,等概率返回一个
        // Math.random() * N -> [0, N) 所有小数,等概率返回一个
        // (int)(Math.random() * N) -> [0, N - 1] 所有的整数,等概率返回一个
        int[] arr = new int[(int)((maxSize + 1) * Math.random())]; // 长度随机
        for(int i = 0; i < arr.length; i++){
            // 随机出来的数有可能是正数有可能是负数,范围是(-maxValue, maxValue]
            arr[i] = (int)((maxValue + 1) * Math.random() - (maxValue) * Math.random());
        }
        return arr;
    }

    // 第二套思路对数组进行排序
    public static void comparator(int[] arr){
        Arrays.sort(arr); // 直接调用语言写好的方法,稳妥!
    }

    // 将原数组的所有元素的内存地址复制一遍
    public static int[] copyArray(int[] arr){
        int[] newArray = new int[arr.length];
        for(int i = 0; i < arr.length; i++){
            newArray[i] = arr[i];
        }
        return newArray;
    }
    // 判断两个数组是否相等
    public static boolean isEqual(int[] arr1, int[] arr2){
        if((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)){
            return false;
        }

        // 这个一定要放在计算arr.length 的上面,先检查空指针,再查看长度
        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;
    }
    public static void printArray(int[] arr){
        if(arr == null){
            return;
        }

        for (int element : arr) {
            System.out.print(element + ", ");
        }
        System.out.println();
    }
}

Reference:
https://segmentfault.com/a/1190000016911927
https://italk.mashibing.com/course/detail/cour_00004003

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容