1,你想要测的方法a(最优解)
2,实现复杂度不好但是容易实现的方法b(暴力解)
3,实现一个随机样本产生器(长度也随机、值也随机)
4,把方法a和方法b跑相同的输入样本,看看得到的结果是否一样
5,如果有一个随机样本使得比对结果不一致,打印这个出错的样本进行人工干预,改对方法a和方法b6,当样本数量很多时比对测试依然正确,可以确定方法a(最优解)已经正确。
· 关键是第5步,找到一个数据量小的错误样本,然后把错误例子带入代码一步一步排查
Print大法、断点技术都可以
对数器的门槛其实是比较高的,因为往往需要在两种不同思路下实现功能相同的两个方法,暴力一个、想象中的最优解是另一个。以后的很多题目都会用到对数器,几乎可以验证任何方法,尤其在验证贪心、观察规律方面很有用到时候会丰富很多对数器的实战用法,这里只是一个简单易懂的示例。
生成随机数组
方法一:
方法二:复制数组
对数器:
对数器的工作方式:
- 设定条件:
- 首先,我们设定了几个参数:
N
表示随机数组的最大长度,V
表示随机数组中每个数的最大值(在1到V之间),testTimes
表示我们要测试的次数。
- 首先,我们设定了几个参数:
- 生成随机数组:
- 每次测试时,对数器都会调用
randomArray
方法来生成一个长度在1到N之间的随机数组,数组中的每个数都在1到V之间。
- 每次测试时,对数器都会调用
- 复制数组:
- 然后,对数器会多次(三次在这个例子中)调用
copyArray
方法来复制这个随机数组。这样做的目的是为了确保我们有一个原始的数组和几个副本,我们可以在不影响原始数组的情况下对这些副本进行排序。
- 然后,对数器会多次(三次在这个例子中)调用
- 排序:
- 接下来,对数器会对这三个副本数组分别使用三种不同的排序算法进行排序:选择排序、冒泡排序和插入排序。
- 检查结果:
- 排序后,对数器会检查这三个排序后的数组是否都相同。理论上,因为这三个数组都是从同一个原始数组复制来的,所以无论使用哪种排序算法,排序后的结果都应该是相同的。
- 如果这三个排序后的数组中有任何两个不相同,对数器就会输出“出错了!”,这意味着可能某个排序算法或者数组复制的过程出了问题。
- 重复测试:
- 这个过程会重复很多次(在这个例子中是50000次),以确保我们的排序算法和数组复制功能在各种情况下都能正常工作。
缩小范围排除错误
当对数器输出“出错了!”时,表明在排序或数组复制的过程中可能存在问题。为了有效地利用对数器来缩小范围并排除错误,你可以采取以下步骤:
1. 仔细检查对数器的实现
首先,确保对数器本身的实现是正确的。这包括:
- 验证
randomArray
函数是否正确生成了预期范围内的随机数组。 - 确保
copyArray
函数正确地复制了数组,没有遗漏或错误地复制元素。 - 检查排序算法的调用是否正确无误,包括传递给它们的参数。
2. 逐步调试
- 单步执行:通过单步执行代码或使用调试工具,观察在出错时数组的状态。注意在排序前和排序后数组的变化。
- 添加打印语句:在排序前后以及关键操作点添加打印语句,输出数组的内容或关键变量的值,以便跟踪程序的执行流程和状态。
3. 分离测试
- 测试数组复制:单独测试
copyArray
函数,确保它能够准确地复制任何给定的数组。 - 测试单个排序算法:分别测试每个排序算法,看它们是否能正确地对数组进行排序。可以使用已知的测试数组来验证排序结果。
4. 缩小测试范围
- 减少测试次数:在调试初期,可以减少
testTimes
的值,以便更快地看到问题所在。 - 简化测试数组:从简单的数组(如已排序或逆序的数组)开始测试,然后逐渐增加复杂度。
5. 使用断言
在代码中添加断言(assertions),以验证关键操作的结果是否符合预期。如果断言失败,则表明在该点出现了问题。
6. 编写单元测试
为对数器和排序算法编写单元测试,以确保它们能够按预期工作。单元测试可以帮助你快速定位问题,并在修改代码后验证问题是否已解决。
7. 分析输出结果
当对数器报告错误时,仔细分析输出的数组内容。查看哪些元素在排序后不一致,这可能会给你提供关于哪个排序算法或哪个复制步骤出错的线索。
8. 求助社区
如果问题仍然难以解决,可以考虑在编程社区或论坛上寻求帮助。提供足够的代码片段和错误描述,以便其他开发者能够理解问题并给出建议。