对拍

也许对大家来说,还不知道什么叫做对拍。其实对拍就是你有一个标准程序(或者暴力程序什么的,只要保证答案正确就行了)和一个答案错误的程序,在尝试很多次以后,肉眼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");
}    

如果错了就会这样:
运行结果

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值