简易对拍器

Posted 2018slgys

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简易对拍器相关的知识,希望对你有一定的参考价值。

技术图片

????????之前写程序WA调试时,一般都是手工造边界数据,然后输出比较,然而这几次的程序大多是数学类的,手工计算出结果非常大,无奈只能上网找AC的代码,然后逐一比较输出的结果,根据<算法竞赛入门经典>最后附录中给出的对拍的例子简单的改了一下,得到了一个简易的对拍器.这个对拍器主要包括下面三个部分:一个是生成随机数据的程序,一个是测试用的程序和一个标程,还有一个进行重定向输入输出比较输出结果的bash脚本.

???????首先是那个随机数据生成器,主要用的是C++的随机数引擎.典型的用法如下:

    // 利用这个可以生成在[0,9]之间均匀分布的随机整数
    uniform_int_distribution<unsigned> u(0, 9);
    default_random_engine e(time(0));
    for(auto i = 0; i < 10; ++i){
        cout<<u(e)<<endl;
    }

用这个可以生成均匀分布的随机的浮点数:

    // 用这个可以生成[0,2]之间的均匀分布的随机浮点数
    uniform_real_distribution<double> v(0, 2);
    default_random_engine e(time(0));
    for (auto i = 0; i < 4; i++)
        cout<<v(e)<<endl;

这里的time(0)作为随机数的种子,保证每一次产生的数据都不一样.

这里使用默认的随机数引擎产生这样一组数据,首先是一个整数t,表示这组数据的范围,然后产生这样(t)对这样的数据,每对数据首先产生一个(n),然后在([1,n))中间随机产生一个整数.对应的程序如下:

    default_random_engine e(time(0));
    uniform_int_distribution<unsigned> T(1, 10);
    auto t = T(e);
    cout<<t<<endl;
    for (int i = 0; i < t; ++i){
        uniform_int_distribution<unsigned> N(2, 20);
        auto n = N(e);
        uniform_int_distribution<unsigned> K(1, n);
        auto k = K(e);
        cout<<n<<" "<<k<<endl;
    }

这样的随机数产生器,只能产生最基本的随机数,如果数据间的约束比较复杂,比如图论中的结点边等,这样的随机数产生器是不够的.

???????这里面使用的测试的程序是一个简单的加法,输入一个整数表示测试的轮次,然后每次读取两个数据,然后对这两个数据做加法,但是其中一个会稍稍改动一下,保证会有一半的概率输出错误的结果,就是当读到一个偶数是会输出0.

#include <bits/stdc++.h>
using namespace std;

int main(){
    int top = 0;
    scanf("%d",&top);
    while(top--){
        int n,k;
        scanf("%d%d",&n,&k);
        // 错误的情况,第二次测试时改为正确的a+b
        if( n % 2 == 0 ){
            printf("0
");
        }else{
            printf("%d
", n+k);
        }
    }
}

???????这个是脚本,用来重定向随机数的输出到一个文件,然后将这个文件作为数据文件输入到测试的程序中,测试的程序会将结果输出到文件,然后利用diff比较这两个文件的内容.如果两个程序输出的结果某一行不一致,diff会列出这个不一致的地方.如果这组数据完全一样,会随机再产生一组数据,再进行一次测试.

#!/bin/bash

# 对拍器
cnt=0;

while (($cnt < 32))
do
    let "cnt++"
    ./r > input
    ./a < input > output.a
    ./b < input > output.b
    diff output.a output.b
    if [ $? != 0 ]
    then 
        echo "WA"
        break;
    fi;
done;

if [ $cnt == 32 ]
then 
    echo "After $cnt Test cases passed, Maybe AC" 
fi;

这里的cnt用来控制测试轮次,这里设置为32次.意思是当一轮测试为真,会再产生一组随机数进行测试,直到测试轮次到达32时计数测试,输出一个"After $cnt Test cases passed, Maybe AC"的提示性语句;如果比较输出结果时中间有一组数据不一致,那么会输出这两个程序的结果的差异的地方,然后通过查看输入数据来debug.下面的图片展示的是测试运行的结果:

技术图片

以上是关于简易对拍器的主要内容,如果未能解决你的问题,请参考以下文章

排序之冒泡排序+对拍器的使用

使用远程 IO 针对设定长度的节拍器录制

Guitar Pro 5 节拍器不响

ACM之对拍

模板对拍程序

查错神器——对拍