我的ACM题目测试数据产生方法

到网上搜了下ACM题目产生方法,却没有搜索到有用的资料,那只能自己钻研一下了,下面把钻研出的结果给大家分享一下。

我们知道,ACM的题目对算法要求很高,OJ上而如何评判一个算法的复杂度靠的是测试数据。一般地,题目需要数据量比较大,不可能人工地去产生,只能借助计算机产生测试数据,而为了避免数据出现规律性,那应该尽量让数据随机。接下来,我们就研究最一般的问题,如何产生int,long long ,大整数,以及字符串?

我们知道,C语言提供了我们一个随机函数rand(),可惜的是它只能产生(1~2^15-1)以内的数据。远远满足不了我们对int 型数据的需求(-2^31,2^31-1),更不用说long long 型和大整数了。

那么一种办法是利用 x=rand()/(2^15-1)*(2^31-1),这样做的结果范围是变大了,但是导致有些数根本不会出现,例如rand()等于0的时候,x=0,当rand()等于1的时候,x=(2^31-1)/(2^15-1)所以会导致(0,(2^31-1)/(2^15-1))之间的数根本不会出现。

下面利用了一种简单的算法产生随机数

由于最后产生的数据都要存入文本文档,所以以字符串表示的整数和以int型表示存进去没有差别,这里统一以字符串形式存入文本文档。

1.先随机产生一个数字n,代表即将产生一个n位数

2.对于这个n位数,每位上的数字都随机产生

这样就可以实现构造一个int型数了。

下面是随机产生int型数据的代码

#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#include<fstream>
#define digit 10
using namespace std;
string LLMax="9223372036854775807";
string IntMax="2147483647";
string RandomInt()
{
    int n=rand()%digit+1;//接下来生成n位数
    string s;
    if(n==digit)//特殊处理,因为int型要在[-2^31,2^31-1]之内
    {
        s+=rand()%2+1+'0';
        for(int i=1;i<n;i++)
        {
            int temp=rand()%10;
            while(temp>IntMax[i]-'0') temp=rand()%10;
            s+=temp+'0';
        }
        return s;
    }
    if(n==1) s+=rand()%10+'0';//
    else s+=rand()%9+1+'0';//第一位为1-9之间的数
    for(int i=2;i<=n;i++) s+=rand()%10+'0';//随机产生第2-n位上的数字
    if(rand()%2==1) s='-'+s;//产生负数
    return s;
}
int main()
{
    int m=0;
    ofstream in("int_in.txt");
    srand((unsigned)time(NULL));
    for(int i=0;i<100;i++)
        in<<RandomInt()<<endl;
    return 0;
}

同理可以产生 long long型的

代码如下

#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#define digit 19
using namespace std;
string LLMax="9223372036854775807";
string IntMax="2147483647";
string RandomLL()
{
    int n=rand()%digit+1;//接下来生成n位数
    string s;
    if(n==digit)//特殊处理,因为int型要在[-2^63,2^63-1]之内
    {
        s+=rand()%9+1+'0';
        for(int i=1;i<n;i++)
        {
            int temp=rand()%10;
            while(temp>LLMax[i]-'0') temp=rand()%10;
            s+=temp+'0';
        }
        return s;
    }
    if(n==1) s+=rand()%10+'0';//
    else s+=rand()%9+1+'0';//第一位为1-9之间的数
    for(int i=2;i<=n;i++) s+=rand()%10+'0';//随机产生第2-n位上的数字
    if(rand()%2==1) s='-'+s;//产生负数
    return s;
}
int main()
{
    int m=0;
    srand((unsigned)time(NULL));
    for(int i=0;i<100;i++)
        cout<<RandomLL()<<endl;
    return 0;
}

产生大整数

#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#include<fstream>
#define digit 100
using namespace std;
string LLMax="9223372036854775807";
string IntMax="2147483647";
string RandomBigInteger()
{
    int n=rand()%digit+1;//接下来生成n位数
    string s;
    if(n==1) s+=rand()%10+'0';//
    else s+=rand()%9+1+'0';//第一位为1-9之间的数
    for(int i=2;i<=n;i++) s+=rand()%10+'0';//随机产生第2-n位上的数字
    //if(rand()%2==1) s='-'+s;//产生负数
    return s;
}
int main()
{
    int m=0;
    ofstream in("in.txt");
    srand((unsigned)time(NULL));
    for(int i=0;i<100;i++)
        in<<RandomBigInteger()<<endl;
    return 0;
}

产生字符串

#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#define digit 30
using namespace std;
string LLMax="9223372036854775807";
string IntMax="2147483647";
string SmellAlphabet="abcdefghijklmnopqrstuvwxyz";
string UpperAlphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string RandomString()
{
    int n=rand()%digit+1;//接下来生成n位字符串
    string s;
    for(int i=0;i<n;i++) s+=SmellAlphabet[rand()%26];//随机产生字符串
    return s;
}
int main()
{
    int m=0;
    srand((unsigned)time(NULL));
    for(int i=0;i<100;i++)
        cout<<RandomString()<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值