• 痛定思痛:一次失败的重构


    最近搞了一个算法,寻找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的元素是什么。

  • 相关阅读:
    VS2008 环境中完美搭建 Qt 4.7.4 静态编译的调试与发布 Inchroy's Blog 博客频道 CSDN.NET
    编写可丢弃的代码
    c++ using namespace std; 海明威 博客园
    解决MySQL server has gone away
    nginx upstream 调度策略
    (2006, 'MySQL server has gone away') 错误解决 dba007的空间 51CTO技术博客
    Linux IO模型漫谈(2) 轩脉刃 博客园
    redis源码笔记 initServer 刘浩de技术博客 博客园
    MySQLdb批量插入数据
    词库的扩充百度百科的抓取你知道这些热词吗? rabbit9898 ITeye技术网站
  • 原文地址:https://www.cnblogs.com/alphablox/p/3074929.html
Copyright © 2020-2023  润新知