C++实现一个简单java对拍程序
电梯月官方给的测试数据实在是太水了,多亏了dalao的评测机我才能够发现自己的bug。
对于电梯而言,因为其为多线程,且不限制调度防止,导致了其最终结果的多样。因此需要写一个程序专门来进程正确性的判断。
对于一般的串行程序,其结果唯一,因此并不需要专门写一个正确性判断程序,只需要多找几个人的程序进行对拍就好了,省时又高效。
在此简述如何使用cpp实现一个对拍程序。
总体设计
对拍器主要要做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个好处
- 运行起来的命令很简单
- 向同学要代码时,不需一整个项目的文件,只要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;
}