文章目录
用于C语言数据点生成、运行、比较的几段代码
做题的时候有几个数据点过不去一直wa的时候,自己又懒得动脑子想特殊情况。笔者就一直想怎么生成一些数据点,然后让它自己跑一跑,最后自己看一看,网上搜索了一下数据点生成器,找到这个:
想出OI题?用最简洁的C/C++测试数据生成工具——makedata.h库
这个是C++版本的,而且还将数据点生成代码和输出代码放一块,作为强迫症的笔者自然受不了,于是模仿上文原理写了C语言的数据点的相关工具,话不多说,上代码!
数据点生成makedata
代码
//makedata.h
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include<time.h>
#define max(a, b) ((a > b) ? a : b)
#define min(a, b) ((a < b) ? a : b)
#define num(a, b) ((rand() * RAND_MAX + rand()) % (a - b + 1) + a)
int times = 10;
void filein(int tp)
{
char inname[20];
sprintf(inname, "data%02d.in", tp);
freopen(inname, "w", stdout);
}
void fileclose()
{
fclose(stdin);
fclose(stdout);
}
void makedatain();
int main()
{
srand((unsigned)time(NULL));
for (int tp = 1; tp <= times; ++tp)
{
filein(tp);
makedatain();
fileclose();
}
return 0;
}
//makedata.c
#include"makedata.h"
void makedatain()
{
}
所有的运行原理都打包在.h文件里,.c负责直观,到时候把要运行的代码放在这里就行了(就可以把这个void makedatain
想象成int main
然后进行操作就行了。
举例
还要说明的一点是随机数据点的生成,这里举例a+b:
//a+b
//makedata.c
#include"makedata.h"
void makedatain()
{
int a = num(-1000, 1000), b = num(-1000, 1000);
printf("%d %d", a, b);
}
如图,现在我的输出文件夹里面什么都没有,当我运行这个代码后:
可以看到,在终端什么都没出现,而输出文件夹里生成了可执行文件和10组数据,我们来打开看看这些datain看看:
这里打开4组数据,可以看到,它按照我们的要求生成了-1000到1000的随机数。
数据点运行maindata
代码
//maindata.h
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#define max(a, b) ((a > b) ? a : b)
#define min(a, b) ((a < b) ? a : b)
int times = 10;
void file(int tp)
{
char inname[20], outname[20];
sprintf(inname, "data%02d.in", tp);
sprintf(outname, "data%02d.out", tp);
freopen(inname, "r", stdin);
freopen(outname, "w", stdout);
}
void fileclose()
{
fclose(stdin);
fclose(stdout);
}
void makedataout();
int main()
{
for (int tp = 1; tp <= times; tp++)
{
file(tp);
makedataout();
fileclose();
}
}
//maindata.c
#include "maindata.h"
void makedataout()
{
}
这里也一样,把void makedataout
视作int main
就行,只不过不需要有返回值,即return 0
。这里可以直接搬运你的代码,无论是全局变量还是函数,你可以把它通通按照原来的位置搬过来,剩下的.h已经帮你处理好了。
举例
这里接着上面a+b的例子:
#include "maindata.h"
int a, b;
void makedataout()
{
scanf("%d %d", &a, &b);
printf("%d", a + b);
}
我们运行一下看看:
再横向对比一下数据
这里就展示一组数据,剩下的大家可以自己测一测。
(比较)再运行一组secdata
剩下的就是个人觉得比较好玩的,大概就是模拟一下各OJ平台数据点是怎么测试的。假如说上面的maindata是正确的代码
下面的就是要测试的代码,具体代码和miandata一样,就不多解释了。
代码
//secdata.h
#include<stdio.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#define max(a, b) ((a > b) ? a : b)
#define min(a, b) ((a < b) ? a : b)
int times = 10;
void file(int tp)
{
char inname[20], outname[20];
sprintf(inname, "data%02d.in", tp);
sprintf(outname, "sec%02d.out", tp);
freopen(inname, "r", stdin);
freopen(outname, "w", stdout);
}
void fileclose()
{
fclose(stdin);
fclose(stdout);
}
void cmp();
int main()
{
for (int tp = 1; tp <= times; tp++)
{
file(tp);
cmp();
fileclose();
}
}
//secdata.c
#include "secdata.h"
void cmp()
{
}
举例
#include "secdata.h"
void cmp()
{
printf("478");
}
为了模拟,就在这里输入第一组数据了。
比较代码cmp
//cmp.c
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#define max(a, b) ((a > b) ? a : b)
#define min(a, b) ((a < b) ? a : b)
#define MAX 1024
int times = 10;
FILE *f1, *f2;
void file(int tp)
{
char name1[20], name2[20];
sprintf(name1, "data%02d.out", tp);
sprintf(name2, "sec%02d.out", tp);
f1 = fopen(name1, "r");
f2 = fopen(name2, "r");
}
int main()
{
char f1_line[MAX_LINE], f2_line[MAX_LINE];
for (int tp = 1; tp <= times; tp++)
{
file(tp);
int line = 1;
while (fgets(f1_line, MAX, f1) != NULL && fgets(f2_line, MAX, f2) != NULL)
{
if (strcmp(f1_line, f2_line) != 0)
{
printf("file %02d line %02d is different.\n", tp, line);
break;//这里你如果要对比大量数据,也可以不用break
}
line++;
}
fclose(f1);
fclose(f2);
}
return 0;
}
我们运行一下看看结果:
因为数据范围太大了,所以只有第一个点是符合条件的,这个应该就是各平台用于测数据点的原理了。
总结
这个系列代码可以模拟生成数据点,用于相应数据的测试,还可以进一步通过文件操作进行OJ平台的测试模拟,感兴趣的朋友可以拿来玩玩。
题内话
当时舍友做题时一直得0.7分AC不了,让我帮忙检查一下。是道算矩阵的题目,我当时一打开看——哇,好多for循环。大脑直接宕机,然后就想能不能用自己AC了的代码,模拟数据点,来给他测测哪些点过不了。
结果是,凡是计算幂运算的幂次超过2的,他的点全都跟我的不一样,当时就觉得特别好玩,各位代佬也可以用这个去检查(如果拿不到数据点的话)。
第一次用markdown写,感觉确实很棒,之后会继续学习的!