一个用来造数据的小玩具

· · 个人记录

因为平时有巨量的造数据需求,我自己不太喜欢用 python,所以自己写了一个简单的 cpp 库来简化每次造数据的重复劳动。

代码地址
https://www.luogu.com.cn/paste/softmqwh
使用的标准是 C++20,过后可能会用一些 C++23 的语法。

这个东西的优势大概首先是单文件库,只需要把 hpp 文件放到当前目录下/某个特定目录下就可以直接引用;其次是 cover 了常见需求,比如生成 [1,n][0,n-1] 两个范围的随机整数,还有更方便地直接输出一行若干个可以 cout 的东西(而不需要 std::println);第三是 main 函数写起来很方便,只需要实现 DataGenerator::makeData 方法然后调用就可以了,文末会给出使用这个库造 P13825 数据的示例代码。只需要一次调用,就能够生成所有的测试点(和样例)

后面大概会持续更新这个库,比如添加一键生成一棵树/一张图/自动多测,但应该不会把它弄的太 heavy,否则就和我弄一个很轻的库的初衷相悖了。我只会实现我实践中会用到的高频需求。

:::info[P13825 的数据生成代码]

//本文件是 gen.cc 或 gen.cpp,请把 util.hpp 和本源码,以及 std 的可执行文件放在同一个目录下,编译运行这个文件。
#include "util.hpp"

using namespace util;

void DataGenerator::makeData(int T) {
  int n, q;
  n = 1000'000'000, q = 1'000'00;
  if (T <= 3) n = 8, q = 10;
  else if (T <= 5) n = 1'00'000;
  println(n, q);
  int lim = 1'000'00;
  for (int i = 1; i <= q; ++i) {
    if (T == 10) {
      if (i != q) println(1, 1, n, lim);
      else println(2, 1, n);
    } else {
      int op = mod1(2);
      auto [l, r] = randRange(1, n);
      if (op == 1) {
        println(op, l, r, mod1(lim));
      } else {
        println(op, l, r);
      }
    }
  }
}

int main() {
  util::DataGenerator::run(
    "data",  // 数据名称
    10,      // 测试数据数量
    0,       // 样例数据数量
    "std",   //标程的可执行文件名
    "data",  // 测试数据路径
    "sample" // 样例数据路径
  );
}

:::

使用上文的代码,把编译好的 std,以及 gen 和 util.hpp(本文提供的库)的源代码放在一个目录下编译运行即可。注意 Windows 环境要把 main 函数里 run 方法的 std 参数换成 std.exe

程序会自动创建 datasample 两个子目录,然后根据你在 run 方法里传进去的测试点数量来调用 DataGenerator::makeData(int T)DataGenerator::makeSample(int T) 方法来生成每个测试点/样例点,T 是测试点编号,从 1 开始编号。

util 里的方法应该随便扫一眼源码和命名就知道是干什么的。如果这个玩具有人用的话我再写文档。