zoukankan      html  css  js  c++  java
  • 简易对拍器

    图片

            之前写程序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.下面的图片展示的是测试运行的结果:

    对拍器两次测试输出

  • 相关阅读:
    Spring--AOP--面向切面编程
    Spring ---annotation (重点)--Resource, Component 重要!!!
    Spring ---annotation (重点)--AutoWired 不常用
    ts 交集类型
    ts 使用 keyof typeof
    Dart 编写Api弃用警告
    js 反应&行动
    perl 打印简单的help文档
    perl 在windows上获取当前桌面壁纸
    perl 打印目录结构
  • 原文地址:https://www.cnblogs.com/2018slgys/p/13279177.html
Copyright © 2011-2022 走看看