vlambda博客
学习文章列表

数据结构与算法||对拍程序

对拍程序三步骤:

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.txtstd.exe < in.txt >stdout.txt
第三步:比较两组输出数据比较myout.txtstdout.txt,不用手写,windows自带比较命令:fc(file compare)fc myout.txt stdout.txt比较后,如果相同,会显示找不到差异,否则会显示不同的几行文本
总结:对拍一次命令rand.exe > in.txtmy.exe < in.txt > myout.txtstd.exe < in.txt > stdout.txtfc 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.txtif not errorlevel 1 goto loop //errorlevel是上一个命令的返回值,fc在文件不同时返回1,相同返回0,如果返回0,跳到:looppause //一旦fc返回1,就会执行到这一行暂停,给你时间看数据goto loop//看完数据,按下任意键结束暂停,继续循环

数据生成器rand.cpp程序:

例如:题目格式是T组数据,每组数据一个n,一个m,然后n个1~m的整数#include<bits/stdc++.h>using namespace std;
#define random(a,b) ((a)+rand()%((b)-(a)+1))
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.outif not errorlevel 1 goto loop //errorlevel是上一个命令的返回值,fc在文件不同时返回1,相同返回0,如果返回0,跳到:looppause //一旦fc返回1,就会执行到这一行暂停,给你时间看数据goto loop//看完数据,按下任意键结束暂停,继续循环

优化后的数据生成器rand.cpp:

#include<bits/stdc++.h>using namespace std;
#define random(a,b) ((a)+rand()%((b)-(a)+1))
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.exestd.cpp里放标准程序,编译成std.exe,双击对拍程序,等待暂停,打开data.in就能看对拍数据啦

实践是检验真理的唯一标准

举例:

数据结构与算法||对拍程序

my.cpp

#include<bits/stdc++.h>using namespace std; int main(){ int n; cin>>n; if(n%2==0){ cout<<"even"<<endl; }  return 0; }

std.cpp

#include<bits/stdc++.h>using namespace std; int main(){ int n; cin>>n; if(n%2==0){ cout<<"even"<<endl; }else{ cout<<"odd"<<endl; }  return 0; }

rand.cpp

#include<bits/stdc++.h>using namespace std;
#define random(a,b) ((a)+rand()%((b)-(a)+1))
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

@echo off :loop  rand.exe %random% > data.in my.exe < data.in > my.out std.exe < data.in > std.out fc my.out std.outif not errorlevel 1 goto loop pause goto loop

注意:几个文件一定要待在同一路径下

效果展示:

数据结构与算法||对拍程序

查看data.in

数据结构与算法||对拍程序

查看my.out:啥也没有

数据结构与算法||对拍程序

查看std.out:输出odd,差异性在这里