数据结构与算法||对拍程序
对拍程序三步骤:
1、生成一组输入数据
2、把这组数据分别给两个程序运行,并生成两组输出数据
3、比较两组输出数据
批处理命令:简易对拍程序.bat
新建一个文本文档,后缀改成bat,批处理文件就是一堆命令文本
第一步:生成一组输入数据
把已经写好的数据生成器编译成rand.exe,并放在当前目录下,把
程序的输入重定向到一个文件(freopen操作重定向很麻烦,命令方便)
rand.exe > in.txt
第二步:把这组数据分别给两个程序运行,并生成两组输出数据
如何把文件输入到一个程序中?
my.exe < in.txt //my.exe对应错误程序
std.exe <in .txt//std.exe对应标准程序
如何把两个程序的输出再重定向到文件?
my.exe < in.txt >myout.txt
std.exe < in.txt >stdout.txt
第三步:比较两组输出数据
比较myout.txt和stdout.txt,不用手写,windows自带比较命令:fc(file compare)
fc myout.txt stdout.txt
比较后,如果相同,会显示找不到差异,否则会显示不同的几行文本
总结:对拍一次命令
rand.exe > in.txt
my.exe < in.txt > myout.txt
std.exe < in.txt > stdout.txt
fc myout.txt stdout.txt
如何循环对拍?
@echo off //防止刷屏,关掉输入显示,不然所有的输入命令都会显示出来
:loop //定位标记点,和c语言goto很像
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 //errorlevel是上一个命令的返回值,fc在文件不同时返回1,相同返回0,如果返回0,跳到:loop
pause //一旦fc返回1,就会执行到这一行暂停,给你时间看数据
goto loop//看完数据,按下任意键结束暂停,继续循环
数据生成器rand.cpp程序:
例如:题目格式是T组数据,每组数据一个n,一个m,然后n个1~m的整数
using namespace std;
int main(){
int seed=time(NULL);//随机种子
srand(seed);//设置随机种子
printf("1\n");
int n=10;
int m=random(1,20);
printf("%d %d\n",n,m);
for(int i=0;i<n;i++){
printf(" %d ",random(0,m));
}
printf("\n");
return 0;
}
time(NULL):是一秒才更新一次,随机数据一秒才换一次,太慢!
有没有更快的变换随机种子的方法?
windows自带了一个随机数发生器:%random%,它的值就是一个随机整数,可以在命令行里调用。
把这个数传给rand.exe用来当随机数种子
传入方法:int main(int argc,char *argv[])
argc:参数的个数
*argv[]:参数表,从1开始
@echo off //防止刷屏,关掉输入显示,不然所有的输入命令都会显示出来
:loop //定位标记点,和c语言goto很像
rand.exe %random% > data.in//把%random%当参数传给rand.exe
my.exe < data.in > my.out
std.exe < data.in > std.out
fc my.out std.out
if not errorlevel 1 goto loop //errorlevel是上一个命令的返回值,fc在文件不同时返回1,相同返回0,如果返回0,跳到:loop
pause //一旦fc返回1,就会执行到这一行暂停,给你时间看数据
goto loop//看完数据,按下任意键结束暂停,继续循环
优化后的数据生成器rand.cpp:
using namespace std;
stringstream ss;//把字符串转换成整数
int main(int argc,char *argv[]){
int seed=time(NULL);//随机种子
if(argc){//如果有参数
ss.clear();
ss<<argv[1];
ss>>seed;//把参数转换成整数赋值给seed
}
srand(seed);//设置随机种子
//以上为随机数初始化,请勿修改,random(a,b)生成[a,b]的随机整数
//下面写自己的数据生成代码
printf("1\n");
int n=10;
int m=random(1,20);
printf("%d %d\n",n,m);
for(int i=0;i<n;i++){
printf(" %d ",random(0,m));
}
printf("\n");
return 0;
}
继续完成最后一步操作
把my.cpp和std.cpp放在和对拍程序相同的目录下,my.cpp里放自己的代码,编译成my.exe
std.cpp里放标准程序,编译成std.exe,双击对拍程序,等待暂停,打开data.in就能看对拍数据啦
实践是检验真理的唯一标准
举例:
my.cpp
using namespace std;
int main(){
int n;
cin>>n;
if(n%2==0){
cout<<"even"<<endl;
}
return 0;
}
std.cpp
using namespace std;
int main(){
int n;
cin>>n;
if(n%2==0){
cout<<"even"<<endl;
}else{
cout<<"odd"<<endl;
}
return 0;
}
rand.cpp
using namespace std;
stringstream ss;//把字符串转换成整数
int main(int argc,char *argv[]){
int seed=time(NULL);//随机种子
if(argc){//如果有参数
ss.clear();
ss<<argv[1];
ss>>seed;//把参数转换成整数赋值给seed
}
srand(seed);//设置随机种子
//以上为随机数初始化,请勿修改,random(a,b)生成[a,b]的随机整数
//下面写自己的数据生成代码
int m=random(1,1000);
printf("%d",m);
printf("\n");
return 0;
}
对拍.bat
off
:loop
rand.exe %random% > data.in
my.exe < data.in > my.out
std.exe < data.in > std.out
fc my.out std.out
if not errorlevel 1 goto loop
pause
goto loop
注意:几个文件一定要待在同一路径下
效果展示:
查看data.in
查看my.out:啥也没有
查看std.out:输出odd,差异性在这里