对拍程序写法

匿名 (未验证) 提交于 2019-12-03 00:30:01

搞信息学竞赛的我们常常会因为WA而苦恼――明明自己的测试数据都是对的怎么一提交就错了呢?这里介绍一种方法――对拍,它能使我们不耗费多余的时间苦苦手打测试数据。

实现方法

对拍,顾名思义,就是将两个程序给相同的输入,看看输出是否一样。

既然如此,我们就需要几个步骤来实现它:

  1. 生成测试数据;
  2. 两个程序分别跑一遍,生成两个输出;
  3. 比较两个输出。

有人可能看到这里觉得可以用文件操作来完成。没错,是可以完成,但容易出错。而一种更方便也更能装逼的方法就是对拍了。

准备材料

  1. 你自己的程序;
  2. 不一定高效,但保证正确的程序;
  3. 数据生成器;
  4. 对拍程序。

第1、2项不多说,只需注意要把这4项放在同一个文件夹里。现在重点说说第3、4项。

3.数据生成器

#include<iostream> #include<cstdlib>//rand()需包含头文件 using namespace std; int main(int argc,char *argv[]){ 	printf("%d %d",rand()%10+1,rand()%10+1);//生成1~10的随机数 	return 0; }

最简单的随机数生成器就完成了!我们暂且将它称为baby数据生成器

看到这里的小伙伴不要太激动,如果你把这份代码拷贝下来运行几次后,你会发现每次生成的两个随机数都是一样的。这是因为我们没有设置随机数种子,所以,下一步,我们要设置随机数种子。

#include<iostream> #include<time.h> #include<cstdlib> using namespace std; int main(int argc,char *argv[]){ 	srand(time(NULL));//加上这条代码,就是将现在时间设为随机数种子的意思 	printf("%d %d",rand()%10+1,rand()%10+1); 	return 0; }

好了,数据生成器2.0完成了,我们把它称为简易版数据生成器

但是,这样还不够完美,因为time(NULL)一秒才能更新一次,也就是说我们的简易版数据生成器要至少一秒才能生成一个数据,太慢了!具体怎么优化,我们等讲完对拍程序了再说。

4.对拍程序

首先,我们新建一个批处理文件。啥?你居然不会?右键单击――点击新建――新建文本文档――将文本文档后缀名改成 .bat 即可。什么?你不会更改后缀名?点击计算机――点击左上角的查看――将文件后缀名勾选框打勾。

好了,我们有了一个批处理文件。右键单击它――点击编辑。

1.生成一组数据:假设你的数据生成器命名为rand.exe。现在,我们把这个测试数据重定向到一个文本里。

rand.exe > in.txt

是不是hin简单?接下来,我们把文件输入到程序里。

rand.exe > in.txt my.exe < in.txt right.exe < in.txt

其中,数据生成器、自己的程序、正确的程序的名字可以自己自定义。

第3步:把输出重定向到另一个文件里

rand.exe > in.txt my.exe < in.txt > my.txt right.exe < in.txt > right.txt

最后,比较两个文件(比较命令:fc)

rand.exe > in.txt my.exe < in.txt > my.txt right.exe < in.txt > right.txt fc my.txt right.txt

好了,baby对拍程序写好了!

抽筋。

那么,能不能循环呢?当然可以!

@echo off :start rand.exe > in.txt my.exe < in.txt > my.txt right.exe < in.txt > right.txt fc my.txt right.txt if not errorlevel 1 goto start set /p in=<in.txt echo %in% pause goto start

哎哎,看不懂的兄台憋走啊!

给你解释好行了吧~

@echo off表示关闭回显

:start 是一个标记,用于循环

中间部分我就不讲了

if not errorlevel 1 goto start ,errorlevel是上一个语句的返回值,在文件不同时返回1,否则返回0;goto start就是循环

pause ,暂停,给你看数据

ps:如果有某些细节写错了,大佬们帮忙修正下哈

但是,这还不够,我们再看回数据生成器。

相信很多人还不知道main函数里的两个参数是什么意思吧,其实argc就是传人的函数个数,*argv[]就是参数表。

前面我们说到,time(NULL)制造的随机数种子效率太慢,其实,windows中还自带一个随机数生成器――%random%

那么,数据生成器可以优化成这样:

#include<iostream> #include<time.h> #include<cstdlib> #include<sstream> using namespace std; stringstream s; int main(int argc,char *argv[]){ 	int random; 	if(argc>1){//就是把字符串转化成整数,用其他方法也行 		s.clear(); 		ss<<argv[1]; 		ss>>random; 	} 	srand(random); 	printf("%d %d",rand()%10+1,rand()%10+1); 	return 0; }

stringstream使用方法参考这里

然后,对拍程序里这么写:

@echo off :start rand.exe %random% > in.txt my.exe < in.txt > my.txt right.exe < in.txt > right.txt fc my.txt right.txt if not errorlevel 1 goto start set /p in=<in.txt echo %in% pause goto start

好了,这下大功告成!我们可以用超级无敌宇宙霹雳吊炸天数据生成器超级无敌宇宙霹雳吊炸天对拍程序愉快地玩耍了!

ps:别对名字有太大意见啦~

文章来源: 对拍程序写法
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!