小朋友學演算法:對拍程式
一、介紹
在做題或者正式比賽過程中,有時候因為樣例有坑所以直接過了樣例,然後拿去評測結果發現全WA。那如何在這種情況下檢查自己程式或演算法的正確性呢?對拍是一個簡便省事的方案。
所謂“對拍”,顧名思義,就是讓兩者相互比對。所謂“兩者”,一是你要測試的程式,二是一個答案在該程式在一定範圍(時間/空間)內結果必定正確的程式(一般是用暴力求解的程式)。
兩個程式準備好編譯好了以後,就可以開始準備測試用的輸入樣例了。但是輸入樣例要是人為準備起來的話肯定浪費時間還費腦,更別提在正式比賽的時候了。人腦靠不住,那就靠電腦。
為了讓測試的樣例更全面,我們可以用偽隨機數的方法。我們需要用到這幾個的標頭檔案:
#include <ctime> #include <cstdlib>
首先利用srand()函式在隨機數表中找一個點,作為取隨機數的起始點。但是如何做到每次選不同的起始點來取數呢?時間是一直在變化的,所以用time(0)取系統時間放入srand()函式中去,每次取的起始點都不一樣。如果用固定值的話,每次取得的隨機數都會是一樣的。
接下來,就按照輸入格式用rand() 函式將輸入樣例的每個變數賦隨機值。考慮到輸入資料的範圍問題,若在0~n的範圍內,rand()%n就可以使隨機數範圍控制在[0, n)內了;若是在[1, n)內,因為隨機數下限為0,所以rand()%(n-1)+1就把隨機數控制在了該範圍內。以此類推,若在[m, n)範圍內,生成隨機數的公式就為rand()%(n-m)+m。
最後將變數嚴格按輸入格式輸出就好了,後續步驟可以把輸出的資料新增到 .in檔案裡。
有了相比對的程式,有了隨機數生成器,現在就差一個“發動機”兼“處理機”了。
為了進行多次對拍以及處理對拍程式輸出的異同,我們需要一個程式可以進行給定次數下的對拍,並且在有結果不同時停止。寫這個程式時需要用到這個標頭檔案:
#include <windows.h>
首先我們要人為規定進行對拍的次數,在這裡咱們可以規定 cnt = 100,即進行100次對拍。然後在一層while(cnt--)的迴圈裡進行對拍。在迴圈裡層,我們需要把隨機數生成器生成的資料通過程式碼寫入 .in檔案裡,然後將 .in檔案分別通過兩個程式執行,最後比對兩個程式 .out檔案的內容,若相同,則繼續下一次對拍,若不同,則停止對拍。注意要把所有.cpp檔案放在同一個資料夾中,執行對拍程式即可。
二、程式舉例
1 add.cpp
#include <stdio.h> int main() { int a,b; scanf("%d %d", &a, &b); printf("%d\n", a+b); return 0; }
2 add2.cpp對照程式
#include <stdio.h> int main() { int a,b; scanf("%d %d",&a, &b); while(b--) { a++; } printf("%d\n", a); return 0; }
注意,假如a + b = c,則b自減1和a自加1後,仍有a + b = c。所以這個程式可以用來檢驗上一個加法程式是否正確。
3 data.cpp生成隨機資料
#include <stdio.h> #include <ctime> #include <cstdlib> using namespace std; int main() { srand(time(0)); int a,b; a=rand(); b=rand(); printf("%d %d",a,b); return 0; }
4 對拍程式
#include <stdio.h> #include <windows.h> using namespace std; int main() { int cnt = 100; while(cnt--) { system("g++ data.cpp -o data");// compile to generate data.exe system("data > a+b.in");// run data.exe to generate data, and write the data to a+b.in system("g++ add.cpp -o add"); system("add < a+b.in > add.out");// force.exe read data from a+b.in, then write the result to force.out system("g++ add2.cpp -o add2"); system("add2 < a+b.in > add2.out"); if(system("fc add.out add2.out"))// file compare { break; } } system("pause"); return 0; }
執行duipai.cpp後,所得結果為

1.png
少兒程式設計、資訊學競賽諮詢請加微信307591841或QQ群581357582

資訊學競賽公眾號.jpg