1. 程式人生 > 其它 >C++實現一個簡單java對拍程式

C++實現一個簡單java對拍程式

電梯月官方給的測試資料實在是太水了,多虧了dalao的評測機我才能夠發現自己的bug。

對於電梯而言,因為其為多執行緒,且不限制排程防止,導致了其最終結果的多樣。因此需要寫一個程式專門來程序正確性的判斷。
對於一般的序列程式,其結果唯一,因此並不需要專門寫一個正確性判斷程式,只需要多找幾個人的程式進行對拍就好了,省時又高效。

在此簡述如何使用cpp實現一個對拍程式。

總體設計

對拍器主要要做3步:

  1. 資料生成
  2. 執行程式
  3. 比較結果

最後的檔案結構

tester
	|- generator			
    	|- generator.cpp		// 隨機資料生成器
    	|- special_generator.cpp
    |- input					// 存放輸入資料
    	|- in.txt				// 隨機資料生成器生成的輸入,每次都會重新整理
    |- output1
    	|- out.txt				// Mycode.jar的輸出
    |- output2
    	|- out.txt				// HisCode.jar的輸出
    |- tester.cpp				// 對拍程式
    |- MyCode.jar
    |- HisCode.jar

對拍器

其需要呼叫相應的程式以實現以上的三個步驟:

在此處藉助system()函式,通過命令列呼叫來操作。(需要#include <cstdlib>)

第一步:資料生成

system(".\\data_generator\\generator.exe");其會執行generator.exe,新生成一組資料並存到.\\input\\in.txt中。

第二步:執行程式

我選擇先在IDEA中將程式打包成jar包,然後進行測試,這樣有至少以下的2個好處

  1. 執行起來的命令很簡單
  2. 向同學要程式碼時,不需一整個專案的檔案,只要jar包即可

只需要使用system("java -jar MyCode.jar")

就可以執行jar包,在cmd輸入相應命令,就可以在鍵盤中輸入同時在終端中看到結果。現在需要將其改成檔案輸入和檔案輸出。

可以:使用< file.txt將file.txt作為輸入。可以寫成:system("java -jar MyCode.jar < .\\input\\in.txt > .\\output\\out.txt")。這樣就實現了檔案讀入和檔案輸出。

第三步:比較結果

使用命令fc file1.txt file2.txt來比較兩個檔案,其相同時返回0,否則返回一個非0值。所以可以採用如下寫法

 if (system("fc .\\output\\out.txt .\\zgy_output\\out.txt")) {
    printf("發現錯誤!!!\n");
    return 0;
} else {
    printf("通過第%d組隨機資料\n", i);
}

通過簡單潤色修改,最後的對拍程式如下:

// tester.cpp

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <string>
#include <iostream>
#include <Windows.h>
using namespace std;

int main() {
    int random_test_time = 800;  // 測試800組隨機資料
    double start_time1, end_time1;
    double start_time2, end_time2;

    for (int i = 1; i <= random_test_time; i++) {
        printf("===================================================\n");

        system(".\\data_generator\\generator.exe"); // 生成隨機資料

        start_time1 = clock();	// 記錄程式開始的時間
        system("java -jar MyCode.jar < .\\input\\in.txt > .\\output1\\out.txt");
        end_time1 = clock();	// 記錄程式結束的時間,最後相減就是執行的時間

        start_time2 = clock();
        system("java -jar HisCode.jar < .\\input\\in.txt > .\\output2\\out.txt");
        end_time2 = clock();

        if (system("fc .\\output1\\out.txt .\\output2\\out.txt")) {
            printf("發現錯誤!!!\n");
            printf("your code's run time : %.1lf s\n", (end_time1 - start_time1) / 1000);
            printf("test code's run time : %.1lf s\n", (end_time2 - start_time2) / 1000);
            return 0;
        } else {
            printf("通過第%d組隨機資料\n", i);
            printf("your code's run time : %.1lf s\n", (end_time1 - start_time1) / 1000);
            printf("test code's run time : %.1lf s\n", (end_time2 - start_time2) / 1000);
        }

        printf("===================================================\n\n\n\n");
        Sleep(1000);	// 停頓一下,讓資料生成程式取到不同的時間種子
    }
    return 0;
}

執行結果如圖所示:

資料生成器

一般包括2種:隨機大資料,特徵資料。

此處介紹隨機大資料生成一個模板。其會隨機生成3000個隨機數,一行一個。

#include <cstdio>
#include <cstdlib>
#include <ctime>
using namespace std;

int main() {
    static int Total_Request_Num = 3000;
    FILE *out;
    out = fopen(".\\input\\in.txt", "w");	// 尤其注意此處,當tester.cpp呼叫此程式時,"."是tester.cpp所在的位置,不是當前的generator.cpp
    //out = fopen("..\\input\\in.txt", "w");
    srand(time(0));

  	for (int i = 0; i < Total_Request_Num; i++){
		fprintf(out, "%d\n", rand() % 1001);
	}
    fclose(out);
    return 0;
}