也许对大家来说,还不知道什么叫做对拍。其实对拍就是你有一个标准程序(或者暴力程序什么的,只要保证答案正确就行了)和一个答案错误的程序,在尝试很多次以后,肉眼debug不出来,也不知道哪里错了,错在哪一组数据。这时就不要在进行十分麻烦的手动测试,而是用对拍程序来找出错误的地方,及那组让你WA的数据。
对拍,需要4个东西:你的错误程序,答案正确的程序,一个数据生成器,和一个对拍器。
WA程序和标程都呵呵,我们直接讲数据生成器和对排器吧。。。
数据生成器
通常,大家都是一个一个手打数据,这样效率也不高,那怎么办呢?当然是生成随机数据,然后再让两个程序对拍啊。
怎么生成随机数呢?
很简单:
#include<cstdio>
#include<ctime>
#include<cstdlib>//这两个头文件不可少
int main()
{
srand((unsigned)time(NULL));//程序开头写上这一句
printf("%d %d\n",rand()%10,rand()%10);
}
以上是生成0~9之间整数的程序。
为什么是0-9之间?
rand()就是生成一个随机数(由于前面的一句是以time为标准,所以rand()会根据时间生成一个正整数,但不相同),但是它有可能会很大,所以我们通常在后面mod(%)一个数,如果%x,范围就是0~x-1.
举例
比如,a+b问题,我们可以这样写我们的数据生成器:
#include<cstdio>
#include<ctime>
#include<cstdlib>
//这两个头文件不可少
int main()
{
srand((unsigned)time(NULL));//程序开头写上这一句
printf("%d %d\n",rand()%2147438647,rand()%2147438647);
}//2147438647为int最大值
对拍器
首先,我们知道运行源代码后会有一个exe文件,把要对拍的两个程序生成的exe文件放在一个文件夹中。
比如这两个程序:(简单点嘛,⊙﹏⊙b汗)
/*程序1*/
#include<cstdio>
void getint(int &x){
x=0;
char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';
ch=getchar();
}
}
int main()
{
int a,b;
getint(a);getint(b);
printf("%d",a+b);
}
/*程序2*/
#include<cstdio>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d",a+b);
}
编译了就这样:
放在同一个文件夹里:
再做一个数据生成器,用同样的办法将它的exe文件放在这个文件夹中:
/*数据生成器,生成int类型的整数*/
#include<cstdio>
#include<ctime>
#include<cstdlib>
//这两个头文件不可少
int main()
{
srand((unsigned)time(NULL));//程序开头写上这一句
printf("%d %d\n",rand()%2147438647,rand()%2147438647);
}//2147438647为int最大值
然后,就变成这样子:
然后就是对拍程序,有两个版本:
bat文件
@echo off
:loop
rand.exe > in.txt
my.exe < in.txt > myout.txt
std.exe < in.txt > stdout.txt
fc myout.txt stdout.txt
if not errorlevel 1 goto loop
pause
goto loop
这个版本就是一直对比,直到结果不同为止。
c++版本
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
while(1){
system("data.exe > data.txt");
system("1.exe < data.txt > 1.txt");
system("2.exe < data.txt > 2.txt");
if(system("fc 2.txt 1.txt"))//此处也是有返回值的,如果有错误返回1
cout<<"error"<<endl;
}
}
这里是个模板:
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
int t=这里是检查(对拍)次数;
while(t--)
{
system("这里写数据生成器名称.exe > 这里写数据生成器名称.txt");
system("这里写程序1名称.exe < 这里写数据生成器名称.txt > 这里写程序1名称.txt");
system("这里写程序2名称.exe < 这里写数据生成器名称.txt > 这里写程序2名称.txt");
if(system("fc 这里写程序2名称.txt 这里写程序1名称.txt"))
break;
}
if(t==0)
cout<<"no error"<<endl;
else
cout<<"error"<<endl;
return 0;
}
这个是有对拍次数的。
运行结果:
以下没有对拍次数,知道错了为止。
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
while(1)
{
system("这里写数据生成器名称.exe > 这里写数据生成器名称.txt");
system("这里写程序1名称.exe < 这里写数据生成器名称.txt > 这里写程序1名称.txt");
system("这里写程序2名称.exe < 这里写数据生成器名称.txt > 这里写程序2名称.txt");
if(system("fc 这里写程序2名称.txt 这里写程序1名称.txt"))
break;
}
system("pause");
}
如果错了就会这样: