zoukankan      html  css  js  c++  java
  • 关于Linux环境下的对拍

    关于Linux环境下的对拍

    前言

    • 在OI竞赛中,日常训练Debug以及考场上验证正解的正确性,我们经常将自己的 Bug 代码和同学的正确性未知的代码做人眼比对,咳咳,当然不,还是要用电脑做对拍,效率更高,查错更快。

    Method

    • 显然,我们需要四组代码,一个亟待Debug的代码,一组正确代码,一组随机数生成器(后续),以及对拍程序。
    • 以信息竞赛经典算法——排序(据说可能面试要用?)为例,我们用到sort冒泡排序,详情见代码块。
    • std.cpp
      int main(){
          freopen("std.out", "w", stdout);
      	cin >> n;
      	for(int i = 1; i <= n; i++)
      		cin >> a[i];
      	sort(a + 1, a + 1 + n);//stable_sort同理
      	for(int i = 1; i <= n; i++)
      		cout << a[i] << " ";
      	return 0;
      }
      
      
    • tmp.cpp
      int main(){
          freopen("tmp.out", "w", stdout);
      	cin >> n;
      	for(int i = 1; i <= n; i++)
      		cin >> a[i];
      	for(int i = 1; i <= n; i++)
      		for(int j = i + 1; j <= n; j++)
      			if(a[i] > a[j])	swap(a[i], a[j]);
      	for(int i = 1; i <= n ;i++)
      		cout << a[i] << " ";
      	return 0;
      }
      
      
    • rand.cpp
      关于数据生成,每道题需要的数据不一样,
      #include <iostream>
      #include <ctime>//rand函数需要
      #include <algorithm>
      using namespace std;
      
      int main(){
          freopen("rand.out", "w", stdout);
      	srand(time(NULL));
      	int n = rand() % 10 + 1;
      	cout << n << endl;
      	while(n--){
      		int a = rand() % 100 + 1;
      		cout << a << " ";
      	}
      	cout << endl;
      }
      
      
    • dp.cpp
      由于要进行大量的比对操作,所以选择使用文件对比,否则就失去了对拍的意义
      #include <algorithm>
      using namespace std;
      int main(){
      	int T = 10000;
      	int tot = 0;
      	while(T--){
      		tot++;
      		cout << tot << " ";
      		system("./rand; ./std; ./tmp");
      		if(system("diff std.out tmp.out")){
      			cout << "WA" << endl;
      			return 0;
      		}
      		else cout << "AC" << endl;
      	}
      }
      
      
      上述代码运行时,运行了文件对比函数diff,当两个文件不完全一致时,返回结果true,此时输出“WA”且程序停止运行,将hack数据保存在rand.out中,以便手模查错。

    后续——浅析rand随机数生成函数

    • 这里的数据生成程序是调用的外部程序, 每个数据点都重新运行, 而在linux系统上, time(0)会返回当前时间戳, 即从1970年1月1日0点0分0秒到现在经过的秒数, 所以每秒time(0)的返回值不变, 作为随机数种子时, 每秒内生成的数据也都相同, 那么该怎么修改呢?
    • 首先我们要知道linux系统上一个特殊的设备/dev/urandom, 它提供永不为空的随机二进制数据流, 当然还有更随机的/dev/random。但是/dev/random为了保证随机性可能会中断输出, 相比之下, /dev/urandom不会导致程序堵塞。
    • 更多信息参见内核熵池

    实际应用时, 把/dev/urandom当作一个文件, 使用freopen读入

    freopen("/dev/urandom", "r", stdin);  
    

    然后初始化随机数种子时, 使用getchar()读入:

    srand(getchar()*getchar()*getchar()*time(0));
    

    11.23UPD

    (Shell)

    make data
    make 001
    make 002
    
    ((cnt=1))
    
    while true
    do
    	./data > in
    	./001 < in > 1.out
    	./002 < in > 2.out
    	if diff 1.out 2.out; then
    		printf "# $((cnt++)) Accepted
    ";
    	else 
    		notify-send "Gary"
    		break
    	fi
    done
    
  • 相关阅读:
    报表插件
    开发工具安装运行bug总结
    UML学习笔记
    Asp.net MVC中的ViewData与ViewBag
    mvc 4 Razor (@html.xx)语法大全以及应用
    数据大并发处理
    vs2010常用快捷方式
    asp.net mvc3+EF4.1项目实战
    jquery,javascript常用
    vs2010常见错误
  • 原文地址:https://www.cnblogs.com/rui-4825/p/13306893.html
Copyright © 2011-2022 走看看