数据点生成器

用于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写,感觉确实很棒,之后会继续学习的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值