​CSP复赛复习:测试数据的设计

梁老师
梁老师 北京小升初老师~

0 人点赞了该文章 · 68 浏览




测试数据分很多种。一般而言可以把它们分成小数据、大数据和极限数据三种。

一、小数据

大家学编程的时候就知道写完程序第一件事就是过样例,样例就是一个典型的小数据。小数据有三大优点:

1.易于调试。很多同学对编译器的调试模式有很大的依赖性,静态查错的能力很弱。严格地说这不能算是一个坏习惯,因为调试模式确实给我们带来了高效率,帮助我们在极短的时间找到程序的问题所在。但是调试的弊端就是不能处理大数据量的数据。因此,对于静态查错能力弱而调试能力相对较强的同学而言,小数据很重要,绝大部分的错误都是靠小数据的跟踪调试找到的。

2.易于设计。这一点不用多说。由于数据量小,我们往往可以手工设计质量更高的数据,同时对于数据本身也有直观的了解。与此同时,很多的题都会有所谓的“变态数据”,这和极限数据有着一些不同,它虽然数据量不大,但是剑走偏锋,比如某矩阵题给你一个全都是1的矩阵之类的。这种狡猾的数据在评测的时候往往并不罕见,由于这样那样的原因,我们就栽了跟头。为了使得自己的程序更加强壮,我们需要预先测试自己的程序是否能够通过这样的数据。这种变态数据只能够由我们手工设计,因此一般都是小数据。

3.覆盖面广。对于很多题目而言,测试数据理论上存在无穷多组;但是如果有n<5并且所有数都小于10的限制,那么数据的个数就变得有限了,不妨设是1000组。我们可以通过写一个程序,直接把这1000组小数据全部都制作出来,然后逐个儿测试。虽然这些数据的数据量小,但是由于它们把小数据的所有可能的情况都包括在其中了,因此你的程序的大部分问题都能够在这1000组数据中有所体现。同时,因为是小数据,程序可以在很短的时间内运行出解,例如是0.05秒,这样,1000组数据,也不过只要50秒,完全可以接受。但是要注意,生成所有数据的同时,我们还要写一个效率差,确保正确的程序来验证结果的正确性。因此这种想法至少需要2个程序。(具体操作流程参考“大数据”部分)。

二、大数据

大数据是属于那种数据量比小数据大,同时可以使用较弱的替代算法得到结果的数据。一般的操作流程是这样的:先写一个随机化的制作大数据的程序;然后写一个针对题目的效率较差但是正确性能够保证的使用替代算法的程序;最后使用一个批处理文件,进行多次对比测试,即生成一个数据,然后再比较两个程序的结果。一定要注意这三个程序的文件输入输出和批处理的实现,这些地方很容易出错。

大数据的使用方法和前面讲过的小数据的穷举方法差不多,但是相比之下有些许不同:

1.数据量不同。数据量变大之后,对程序是一个新的挑战,一些更加难以发现的问题可能会显露出来。

2.可以随机化。与小数据不同,由于大数据的数据个数过多,不能够穷举完成,因此推荐使用随机化。而随机化显然比穷举要容易编写得多,因此大数据的实现更加方便。而随机化的缺点是,变态数据未必能够随机到。

而与极限数据相比,大数据的优点是可以使用替代算法。极限数据往往不能使用替代算法,因为替代算法往往不能在几秒钟,几分钟甚至几个小时内得出解。

因此大数据是最值得提倡的,我认为如果条件允许,每一题都应该用大数据来测试一下,确保正确性。

三、极限数据

在很多人的观念里,极限数据是非常重要的一种数据。我发现很多同学在通过样例之后第一个测试的数据就是极限数据。我认为这是一种非常不好的习惯,因为极限数据并没有我们想象的那么重要。我们能够通过极限数据了解到什么呢?无非是我们的程序是否会超时,外加我们的程序是否会越界。事实上一些简单得随机化得到的极限数据或者手工出的带规律的极限数据甚至未必真的能够给我们翔实的信息,因为就算对于这些数据我们的程序能够快速得到结果,我们仍然不知道我们的程序是不是真的不会在处理别的数据时超时或者越界。所谓的极限数据,其实不过是用来测试你的数组有没有越界而已,这才是它的最大的用处。

此外,极限数据容易给你一些虚假的信息。例如你测试一个1000*1000的全是1的矩阵,结果程序在0.01秒内出解了,结果无疑是正确的。于是你得出你的程序不越界、不超时、不错误的结论。一些没有经验的同学甚至可能就不再检查这个程序而努力去完成下一道题。然而这么一个特殊的数据,其实什么问题都说明不了。

因此你又不得不使用特殊数据,因为如果你使用了一个随机的数据,你又不能够确定自己的程序结果是不是正确。

当然,我并没有宣扬以后大家不要再设计极限数据。极限数据仍然有它的重要性。但是它的设计应该是最后一步,在至少设计并测试大数据,确保了程序的正确性之后,再检查程序的极限情况下是不是会超时或越界。一般的测评数据中,极限数据的个数并不会很多,我们不应该因小失大。

虽然对测试数据的种类有了一定的了解,但是很多同学也许对如何测试仍有疑惑。测试程序的原始方法是全部手工的,大致可以概括为:手工运行测试数据生成程序、手工运行源程序、手工运行替代算法的程序,最后目测两个程序的结果是否一样。这个方法虽然直观,但是有很多不可忽视的缺点。比如效率太低,操作时容易有较大误差等。我在这里详细地介绍一下使用批处理的方法。假设我们需要测试一个程序sample.exe,它的输入输出文件分别是sample.in、sample.out,那么首先我们制作一个数据生成程序samplemaker.exe,然后写一个用替代算法的程序sample2.exe,注意这个程序的输入文件是sample.in,但是输出文件是sample2.out。最后写一个txt文件:

Samplemaker.exe

Sample.exe

Sample2.exe

Fc sample.out sample2.out

Pause

然后把这个txt文件的后缀改成bat,就变成了一个批处理文件了。双击运行这个批处理文件,就可以自动测试,得出两个程序的结果是否相同了。Fc命令是用来比较两个文件是否相同,pause表示暂停,以便让我们能够看清楚结果。

但是这个批处理只能够测试一次,我们需要运行它n次来进行n次的测试。这个效率仍然偏低。提高效率的方法是,在批处理文件中加入循环语句,如下:

:loop

Samplemaker.exe

Sample.exe

Sample2.exe

Fc sample.out sample2.out

Pause

Goto loop

这样的话,这个批处理就能够运行无数次,每次你只需要敲一下键盘就可以了。这样的效率已经很高了,你需要做的不过是盯着fc的结果,找到一个不一样的就关掉批处理,找到sample.in,然后调试。

不过,对于有些题目来说,这样的效率仍然不够,1秒可能只能测试几个数据。更好的方法应该是,把pause删除,然后把fc的结果输入进文件,然后写一个程序判断fc的结果,如果发现结果不一样,就把sample.in记录下来。如下:

:loop

Samplemaker.exe

Sample.exe

Sample2.exe

Fc sample.out sample2.out >result.txt

Judge.exe

Goto loop

其中,judge.exe需要我们编写。它应该从result.txt中读入数据,判断结果,如果不一样,就进入死循环(例如使用while true do;语句)。这样你就能够一眼看出有问题出现了,关掉批处理,然后检查sample.in。

图片


添加 家长论坛微信 



发布于 2024-04-03 15:46

免责声明:

本文由 梁老师 原创发布于 家长帮 ,著作权归作者所有。

登录一下,更多精彩内容等你发现,贡献精彩回答,参与评论互动

登录! 还没有账号?去注册

暂无评论

广告
All Rights Reserved Powered BY WeCenter V4.1.0 © 2025 京ICP备20005761号-2