生成引擎是整个工具的地基,网页界面与原生界面调的是同一份实现。入口是一个纯数据接口:前端把参数打包成 JSON POST 过来,后端把文件写到磁盘,再把结果清单回传。
接口参数
| 参数 | 含义 |
|---|---|
start / end | 数据点编号范围,逐个生成 <编号>.in |
count | 每个文件里的元素个数 |
type | 数据类型(见下表) |
r1 / r2 | 整数与浮点数的取值区间 |
strLen | 字符串长度 |
customCharset | 自定义字符集,留空则用该类型的默认字符集 |
perFile | 是否在文件首行写入元素个数 |
extra | 附加变量,逐行写在数据之前 |
outDir / tsDir | 输出目录;tsDir 为真时自动建一个时间戳子目录 |
数据类型
| 索引 | 类型 | 生成方式 |
|---|---|---|
| 0 / 1 | 整数 | 在 [r1, r2] 内取随机值 |
| 2 | 小写字符串 | a-z |
| 3 | 大写字符串 | A-Z |
| 4 | 混合字符串 | a-zA-Z0-9 |
| 5 | 浮点数 | 整数结果除以 100,输出两位小数 |
| 6 | 日期时间 | YYYY-MM-DD HH:MM:SS |
取值范围怎么撑到 64 位
随机数基元是 rand(),但它的返回值只有 15 位有效位,直接取模拿不到 long long 级别的区间。做法是取四次拼成一个 64 位值:
static long long randomLL(long long lo, long long hi) {
if (lo > hi) swap(lo, hi);
long long range = hi - lo + 1;
if (range <= 0) return lo;
long long r = 0;
for (int i = 0; i < 4; ++i) r = (r << 16) | (rand() & 0xFFFF);
return lo + (r % range);
}每次取低 16 位,左移拼接四次即得 64 位随机值,再对区间取模。这样即使 r1、r2 填到 -10^18 ~ 10^18 也能正常生成。
生成主循环
srand((unsigned)time(nullptr));
for (int id = start; id <= endd; ++id) {
wstring path = outDir + L"\\" + to_wstring(id) + L".in";
string content;
if (perFile) content += to_string(count) + "\n"; // 首行写元素个数
for (int i = 0; i < count; ++i)
content += WstrToUtf8Bytes(GenValue(type, r1, r2, slen, chars)) + "\n";
for (auto& ln : extraLines) content += WstrToUtf8Bytes(ln) + "\n";
WriteUtf8File(path, content); // 无 BOM 的 UTF-8
}写法上刻意做了两件事:先在内存里拼好整个文件内容,再一次性落盘(避免几万次小写入拖慢速度);输出统一为无 BOM 的 UTF-8,评测平台按字节读入不会有编码意外。
文件形状随参数变化,例如「首行个数 + 每行一个数」:
10
4813
927
10572
...