zoukankan      html  css  js  c++  java
  • 痛定思痛:一次失败的重构

    最近搞了一个算法,寻找k个有序数组中,顺序为n的那一页数据。最开始的时候,我用假数据填充法处理了一种特殊情况。实现完上线以后,才发现数据填充存在问题。于是赶紧修改。修改完以后,写了case去验证。竟然发现修改前后的版本都能完全通过这些case。我大惑不解,拼命想构造出一组让旧版本fail,而让新版本成功的case,结果只是发现,虽然假数据填充是不对的,但是结论却是对的。

    虽然白白花了两天时间,但是这次经历还是值得铭记的。它让我永远记住,bug是需要验证的,先找出让bug出现的case,再寻找解决bug的方法。而不是按照自己的想象去解决bug,一个根本不存在的bug。

    我的算法的输入输出可以用如下的例子来说明:

    举例来说:

    1 1,2,3,4,5,6,7,8 …
    2 2,4,6,8,10,12 …
    3 3,6,9,12,…

    那么n=8,page=10,应该输出

    1 1,2,3,4,5,6,7,8,9,10,11,12
    2 2,4,6,8,10,12
    3 3,6,9

    注意到被删除的元素刚好是8个,剩下的元素刚好是10个。

    我所采取的算法是取每个队列的 n/3 ,再找出其中的最小值,删除对应的子序列。比如以表一为例,n/3分别是{3,6,9}。其中3对应队列1,是最小的,因此删除队列1的1和2。我称这个过程为寻找guard的过程。找到的guard进行比较,guard最小的队列删除guard之前的元素。看起来没有问题。可是,如果队列的数据不够,n/3对应的位置空缺,guard找不到怎么办。

    我之前的假设是每个队列的后面都有无数个“无穷大”。当guard的位置超过队列的长度,guard都是无穷大,因此怎么都不会是最小。然后无穷大在输出的时候都是最后输出的,不会干扰正常数据的输入。

    但是有个问题容易造成困扰,就是guard小的队列被删除。有可能那个超出范围的队列比“guard败者”的队列更小,删除它,有没有可能删除掉本该出现在结果集的元素呢?不会。因为假设A队列元素个数为x,x<n/3; B队列guard失败,C队列guard成功。那么ABC 3 个队列最多有多少个元素小雨B.guard呢?答案是x+n/3+y.其中x小于n/3,y表示C中小于B.guard的元素个数,也是小于n/3的。因此B.guard怎么都会被删除,不管A的元素是什么。

  • 相关阅读:
    python
    springboot-mybatis-pagehelper(分页插件)
    图片验证码工具类
    http工具类
    page工具类
    生成count位随机数工具类
    日期工具类
    dozer工具类
    list自定义排序工具类
    fastJson工具类
  • 原文地址:https://www.cnblogs.com/alphablox/p/3074929.html
Copyright © 2011-2022 走看看