OJ测试数据生成器

Posted 上山打老虎D

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OJ测试数据生成器相关的知识,希望对你有一定的参考价值。

测试数据生成器


可以使用本文中提到的数据生成器生成OJ中的测试数据,对自己代码进行测试对拍,或对OJ后台数据进行补充。

先序二叉树生成器

基于Python的cyaron库实现。可以生成若干个二叉树的先序序列。

from cyaron import *

global tree
global ans


def outPut(i):
    if i > len(tree) or tree[i] == -1:
        ans.append(0)
        return
    ans.append(tree[i])
    outPut(i * 2 + 1)
    outPut(i * 2 + 2)


if __name__ == '__main__':
    _n = [20, 21, 22, 23, 24, 25, 26]
    _m = ['A']
    for ii in range(1, 5):
        print("working on %d" % ii)
        io = IO(file_prefix="test", data_id=ii)
        n = _n[ii % len(_n)]
        nn = randint(20, 50)
        io.input_writeln(nn)
        for j in range(nn):
            binary_tree = Graph.binary_tree(n)
            ans = []
            tree = [-1] * pow(2, n)
            tree[0] = 1
            for edge in binary_tree.iterate_edges():
                i = 0
                for i in range(0, len(tree)):
                    if tree[i] == edge.start:
                        break
                if tree[i * 2 + 1] == -1:
                    tree[i * 2 + 1] = edge.end
                else:
                    tree[i * 2 + 2] = edge.end
            outPut(0)
            res = ""
            for i in ans:
                if i == 0:
                    res += "0"
                else:
                    res += chr(ord(_m[j % len(_m)]) + i - 1)
            io.input_writeln(res)
        io.output_gen("ans.exe")

哈夫曼树生成器

基于C++实现,便于生成多组测试数据,本生成器可完美适配赫夫曼树的构建与编码,经过修改后可以适配多种题目。为了避免导致因相同权值造成的多解问题导致的可能答案错误,添加了保证哈夫曼树唯一性的检测函数。

#include <iostream>
#include <queue>
#include <random>
#include <vector>
#include <random>
#include <ctime>
#include <set>
#include <algorithm>
#include <map>

using namespace std;

bool checkOnlySolution(vector<int> const v, int const newNumber) 
    set<int> s;
    priority_queue<int, vector<int>, greater<>> pq;
    for (int i = 0; i < v.size(); i++) 
        s.insert(v[i]);
        pq.push(v[i]);
    
    pq.push(newNumber);
    s.insert(newNumber);
    while (pq.size() > 1) 
        int a = pq.top();
        pq.pop();
        s.erase(a);
        int b = pq.top();
        pq.pop();
        s.erase(b);
        if (s.find(a + b) != s.end()) 
            return false;
        
        s.insert(a + b);
        pq.push(a + b);
    
    return true;


int main() 
    srand(time(NULL) * rand() * (time(NULL) % 10));
    freopen("5.in", "w", stdout);
    int totalCases = rand() % 10 + 20;
    cout << totalCases << endl;
    while (totalCases--) 
        int totalNumbers = rand() % 80 + 30;
        cout << totalNumbers;
        vector<int> numbers;
        set<int> s;
        for (int i = 0; i < totalNumbers; i++) 
            int newNumber = rand() % 200 + 1;
            if (s.find(newNumber) == s.end() && checkOnlySolution(numbers, newNumber)) 
                s.insert(newNumber);
                numbers.push_back(newNumber);
             else 
                i--;
                continue;
            
        
        for (int i = 0; i < numbers.size(); i++) 
            cout << " " << numbers[i];
        
        cout << endl;
    
    return 0;

哈夫曼树解码生成器

基于C++实现,便于生成多组测试数据,本生成器可完美适配赫夫曼树解码,经过修改后可以适配多种题目。为了避免导致因相同权值造成的多解问题导致的可能答案错误,添加了保证哈夫曼树唯一性的检测函数,并使用随机数函数生成有解或无解的测试序列。

#include <iostream>
#include <queue>
#include <random>
#include <vector>
#include <random>
#include <ctime>
#include <set>
#include <algorithm>
#include <map>

using namespace std;

class huffman_tree 
public:
    struct node 
        int freq;
        string ch;
        node *left, *right;

        node(int freq, string ch, node *left, node *right) : freq(freq), ch(ch), left(left), right(right) 
    ;

    node *root;
    vector<pair<string, string>> codes;

    huffman_tree(const vector<pair<string, int>> &freq) 
        auto cmp = [](node *a, node *b)  return a->freq > b->freq; ;
        priority_queue<node *, vector<node *>, decltype(cmp)> q(cmp);
        for (auto &p: freq) 
            q.push(new node(p.second, p.first, nullptr, nullptr));
        
        while (q.size() > 1) 
            node *a = q.top();
            q.pop();
            node *b = q.top();
            q.pop();
            q.push(new node(a->freq + b->freq, "0", a, b));
        
        root = q.top();
        q.pop();
        dfs(root, "");
    

    void dfs(node *root, string s) 
        if (root->left == nullptr && root->right == nullptr) 
            codes.push_back(root->ch, s);
            return;
        
        dfs(root->left, s + "0");
        dfs(root->right, s + "1");
    

;

bool checkOnlySolution(vector<int> const v, int const newNumber) 
    set<int> s;
    priority_queue<int, vector<int>, greater<>> pq;
    for (int i = 0; i < v.size(); i++) 
        s.insert(v[i]);
        pq.push(v[i]);
    
    pq.push(newNumber);
    s.insert(newNumber);
    while (pq.size() > 1) 
        int a = pq.top();
        pq.pop();
        s.erase(a);
        int b = pq.top();
        pq.pop();
        s.erase(b);
        if (s.find(a + b) != s.end()) 
            return false;
        
        s.insert(a + b);
        pq.push(a + b);
    
    return true;


vector<string> solve(vector<int> v) 
    vector<int> temp(v);
    sort(temp.begin(), temp.end());
    vector<pair<string, int>> freq;
    for (int i = 0; i < v.size(); i++) 
        freq.emplace_back(to_string(temp[i]), temp[i]);
    
    huffman_tree tree(freq);
    vector<string> res;
    for (int i = 0; i < v.size(); i++) 
        res.push_back(tree.codes[i].second);
    
    return res;


int main() 
    srand(time(NULL) * rand() * (time(NULL) % 10));
    int totalCases = rand() % 10 + 10;
    cout << totalCases << endl;
    vector<char> encodeChars;
    for (int i = 0; i < 26; i++) 
        encodeChars.push_back('a' + i);
        encodeChars.push_back('A' + i);
    
    while (totalCases--) 
        shuffle(encodeChars.begin(), encodeChars.end(), default_random_engine(rand()));
        int totalNumbers = rand() % 35 + 15;
        cout << totalNumbers;
        vector<int> numbers;
        set<int> s;
        for (int i = 0; i < totalNumbers; i++) 
            int newNumber = rand() % 200 + 1;
            if (s.find(newNumber) == s.end() && checkOnlySolution(numbers, newNumber)) 
                s.insert(newNumber);
                numbers.push_back(newNumber);
             else 
                i--;
                continue;
            
        
        for (int i = 0; i < numbers.size(); i++) 
            cout << " " << numbers[i];
        
        cout << endl;
        for (int i = 0; i < numbers.size(); i++) 
            if (i) 
                cout << " ";
            
            cout << encodeChars[i];
        
        cout << endl;
        int totalQueries = rand() % 10 + 5;
        cout << totalQueries << endl;
        while (totalQueries--) 
            bool hasSolution = rand() % 5 != 0;
            if (hasSolution) 
                vector<string> solutions(solve(numbers));
                shuffle(solutions.begin(), solutions.end(), default_random_engine(rand()));
                for (int i = 0; i < rand() % 30 + 20; i++) 
                    cout << solutions[rand() % solutions.size()];
                
             else 
                for (int i = 0; i < rand() % 50 + 50; i++) 
                    cout << rand() % 2;
                
            
            cout << endl;
        
    
    return 0;

多叉树生成器

基于C++实现,便于生成多组测试数据,本生成器可完美适配DS森林叶子编码,经过修改后可以适配多种OJ题,便于生成测试数据进行对拍。

#include <iostream>
#include <queue>
#include <random>
#include 南阳OJ-38 布线问题(最小生成树应用_prim)

OJ网站程序员必备

猿创征文|深度学习前沿应用文本生成

测试:MinMin‘s Online oJ在线OJ项目

MySQL快速生成大量测试数据(100万、1000万、1亿)

oj--考虑多种情况,格式