【基于C++面向WindowAPI的自制工具】随机数按位生成器
[by_041]
主要想到以前要定时抢淘宝限量货品的时候每次都是记录式的编码,导致代码量极大,工程效率极低。
现尝试使用记录操作信息的方式进行操作记录和再现。意义在后期还可以对操作进行分析和优化处理(比如定位优化,速度调整)。
- 不多说了,直接放代码
- 建议直接看最下面注释中标注的三个核心函数,因为引用了早期年少轻狂时候写的大整数处理~~又臭又长~~的代码
- 理念是比如出题时候给出数据范围 0 ≤ v a l < 1 0 9 0\le val < 10^9 0≤val<109,那么就按照等概率随机生成一个9位每位是0~9的数字,位数不为9时亦同理。
- 随机在
毫秒级的等待时间+随机函数+伪随机数矫正(可自行设置概率偏移常数)
取最低位得到一位0~9的随机数
。 - 其中存在的问题其实也很明显,因为采用小时间间隔来防止连续的产生相等的数,所产生随机数的效率较慢,不适用于需要产生大量数据的计算环境。
//#pragma comment(linker, "/STACK:102400000,102400000")
//#pragma GCC optimize ("O2")
#include<bits/stdc++.h>
#include<conio.h>
#include<windows.h>
using namespace std;
typedef long long ll;
//typedef __int64 i64;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define fi first
#define se second
typedef map<int,int> mii;
typedef map<ll,ll> mll;
typedef multiset<int> msii;
typedef multiset<ll> msll;
typedef set<int> sii;
typedef set<ll> sll;
typedef set<pii> spii;
typedef set<pll> spll;
typedef vector<int> vii;
typedef vector<ll> vll;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
#define it_ iterator
#define r_it_ reverse_iterator
namespace BigNum41
{
/*
* 高精度 用vector_int表示正整数
*
*
* 储存方式:
* BigNum_ val;
* val[0]=数字长度;
* val[1]=个位数字;
* val[2]=十位数字;
* ......
* val[val[0]]=最高位数字;
*
*
* 已完成:
* 转换: BigNum_trans (val)
* 转换: BigNum_trans(val,ret)
* 转换: BigNum_trans (str)
* 转换: BigNum_trans(str,ret)
* 转换: BigNum_trans(val,str)
* 输入:++ BigNum_input (val)
* 输出:-- BigNum_output (val)
* 比较:>=,<=,>,<
* 加法:+ BigNum_addition (a,b,ret)
* 减法:- BigNum_subtract (a,b,ret)
* 乘法:* BigNum_multiply (a,b,ret)
* 次方:^ BigNum_power (a,b,ret)
* 阶乘: BigNum_factorial(val,ret)
* 位数: BigNum_resize (ret,val)//十进制位运算
* 除法:/ BigNum_division (a,b,ret)
* 取余:% BigNum_modulo (a,b,ret)
* 大约: BigNum_gcd (a,b)
* 小倍: BigNum_lcm (a,b)
* 大约: BigNum_gcd (a,b,ret)
* 小倍: BigNum_lcm (a,b,ret)
*
* 未完成:
*
*/
#define BigNum_ vector<int>
const BigNum_ BigNum_0 {1, 0};
const BigNum_ BigNum_1 {1, 1};
const BigNum_ BigNum_ERR{1,-1};
BigNum_ BigNum_trans(int val)
{
if(val==0)
return BigNum_0;
BigNum_ ret;
for(ret.push_back(0);val;ret[0]++)
{
ret.push_back(val%10);
val/=10;
}
return ret;
}
void BigNum_trans(int val,BigNum_&ret)
{
ret.clear();
if(val==0)
{
ret=BigNum_0;
return;
}
for(ret.push_back(0);val;ret[0]++)
{
ret.push_back(val%10);
val/=10;
}
return;
}
BigNum_ BigNum_trans(string str)
{
BigNum_ val;
for(auto it:str)
val.push_back(it-'0');
val.push_back(str.size());
reverse(val.begin(),val.end());
return val;
}
void BigNum_trans(string str,BigNum_&ret)
{
ret.clear();
for(auto it:str)
ret.push_back(it-'0');
ret.push_back(str.size());
reverse(ret.begin(),ret.end());
return;
}
void BigNum_trans(BigNum_ val,string&str)
{
str.clear();
for(int i=val[0];i;i--)
str+=(val[i]+'0');
return;
}
void BigNum_input(BigNum_&val)
{
val.clear();
string str;
cin>>str;
for(auto it:str)
val.push_back(it-'0');
val.push_back(str.size());
reverse(val.begin(),val.end());
return;
}
void operator++(BigNum_&val)
{
val.clear();
string str;
cin>>str;
for(auto it:str)
val.push_back(it-'0');
val.push_back(str.size());
reverse(val.begin(),val.end());
return;
}
void operator++(BigNum_&val,int)
{
val.clear();
string str;
cin>>str;
for(auto it:str)
val.push_back(it-'0');
val.push_back(str.size());
reverse(val.begin(),val.end());
return;
}
void BigNum_output(BigNum_ val)
{
for(int i=val[0];i;i--)
putchar(val[i]+'0');
return;
}
void operator--(BigNum_ val)
{
for(int i=val[0];i;i--)
putchar(val[i]+'0');
return;
}
void operator--(BigNum_ val,int)
{
for(int i=val[0];i;i--)
putchar(val[i]+'0');
return;
}
bool operator>=(BigNum_&val_a,BigNum_&val_b)
{
if(val_a[0]^val_b[0])
return val_a[0]>val_b[0];
for(int i=val_a[0];i;i--)
if(val_a[i]^val_b[i])
return val_a[i]>val_b[i];
return true;
}
bool operator<=(BigNum_&val_a,BigNum_&val_b)
{
if(val_a[0]^val_b[0])
return val_a[0]<val_b[0];
for(int i=val_a[0];i;i--)
if(val_a[i]^val_b[i])
return val_a[i]<val_b[i];
return true;
}
bool operator>(BigNum_&val_a,BigNum_&val_b)
{
if(val_a[0]^val_b[0])
return val_a[0]>val_b[0];
for(int i=val_a[0];i;i--)
if(val_a[i]^val_b[i])
return val_a[i]>val_b[i];
return false;
}
bool operator<(BigNum_&val_a,BigNum_&val_b)
{
if(val_a[0]^val_b[0])
return val_a[0]<val_b[0];
for(int i=val_a[0];i;i--)
if(val_a[i]^val_b[i])
return val_a[i]<val_b[i];
return false;
}
void BigNum_addition(BigNum_&val_a,BigNum_&val_b,BigNum_&ret)
{
ret.clear();
ret.push_back(0);
int i,ii=min(val_a[0],val_b[0]),this_dig,next_dig=0;
for(i=1;i<=ii;i++)
{
this_dig=val_a[i]+val_b[i]+next_dig;
next_dig=this_dig/10;
this_dig%=10;
ret.push_back(this_dig);
}
for(ii=val_a[0];i<=ii;i++)
{
this_dig=val_a[i]+next_dig;
next_dig=this_dig/10;
this_dig%=10;
ret.push_back(this_dig);
}
for(ii=val_b[0];i<=ii;i++)
{
this_dig=val_b[i]+next_dig;
next_dig=this_dig/10;
this_dig%=10;
ret.push_back(this_dig);
}
if(next_dig)
{
ret.push_back(next_dig);
i++;
}
ret[0]=i-1;
return;
}
BigNum_ operator+(BigNum_ val_a,BigNum_ val_b)
{
BigNum_ ret;
ret.push_back(0);
int i,ii=min(val_a[0],val_b[0]),this_dig,next_dig=0;
for(i=1;i<=ii;i++)
{
this_dig=val_a[i]+val_b[i]+next_dig;
next_dig=this_dig/10;
this_dig%=10;
ret.push_back(this_dig);
}
for(ii=val_a[0];i<=ii;i++)
{
this_dig=val_a[i]+next_dig;
next_dig=this_dig/10;
this_dig%=10;
ret.push_back(this_dig);
}
for(ii=val_b[0];i<=ii;i++)
{
this_dig=val_b[i]+next_dig;
next_dig=this_dig/10;
this_dig%=10;
ret.push_back(this_dig);
}
if(next_dig)
{
ret.push_back(next_dig);
i++;
}
ret[0]=i-1;
return ret;
}
void BigNum_subtract(BigNum_&val_a,BigNum_&val_b,BigNum_&ret)
{
if(val_a<val_b)
{
BigNum_subtract(val_b,val_a,ret);
return;
}
ret=val_a;
for(int i=val_b[0],j;i;i--)
{
ret[i]-=val_b[i];
if(ret[i]<0)
{
for(j=i+1;!ret[j];j++)
ret[j]=9;
ret[j]--;
ret[i]+=10;
}
}
while(!ret[ret[0]]&&ret[0]>1)
ret[0]--;
ret.resize(ret[0]+1);
return;
}
BigNum_ operator-(BigNum_ val_a,BigNum_ val_b)
{
if(val_a<val_b)
return val_b-val_a;
BigNum_ ret;
ret=val_a;
for(int i=val_b[0],j;i;i--)
{
ret[i]-=val_b[i];
if(ret[i]<0)
{
for(j=i+1;!ret[j];j++)
ret[j]=9;
ret[j]--;
ret[i]+=10;
}
}
while(!ret[ret[0]]&&ret[0]>1)
ret[0]--;
ret.resize(ret[0]+1);
return ret;
}
void BigNum_multiply(BigNum_&val_a,BigNum_&val_b,BigNum_&ret)
{
ret.clear();
ret.push_back(val_a[0]+val_b[0]);
for(int i=1,ii=ret[0],this_dig,next_dig=0;i<=ii;i++)
{
this_dig=next_dig;
for(int j=1;j<=i;j++)
if(val_a[0]>=j&&val_b[0]>=i-j+1)
this_dig+=val_a[j]*val_b[i-j+1];
next_dig=this_dig/10;
this_dig%=10;
ret.push_back(this_dig);
}
ret[0]-=!ret[ret[0]];
return;
}
BigNum_ operator*(BigNum_ val_a,BigNum_ val_b)
{
BigNum_ ret;
ret.push_back(val_a[0]+val_b[0]);
for(int i=1,ii=ret[0],this_dig,next_dig=0;i<=ii;i++)
{
this_dig=next_dig;
for(int j=1;j<=i;j++)
if(val_a[0]>=j&&val_b[0]>=i-j+1)
this_dig+=val_a[j]*val_b[i-j+1];
next_dig=this_dig/10;
this_dig%=10;
ret.push_back(this_dig);
}
ret[0]-=!ret[ret[0]];
return ret;
}
void BigNum_power(BigNum_&val_a,BigNum_&val_b,BigNum_&ret)
{
if(val_b[0]==1)
{
if(val_b[1]==0)
{
ret=BigNum_1;
return;
}
if(val_b[1]==1)
{
ret=val_a;
return;
}
}
if(val_a[0]==1)
if(val_a[1]==1||!val_a[1])
{
ret=val_a;
return;
}
BigNum_ half_b,double_a;
int this_dig,next_dig=0;
half_b=val_b;
for(int i=half_b[0];i;i--)
{
this_dig=next_dig;
next_dig=half_b[i]&1?5:0;
half_b[i]=half_b[i]/2+this_dig;
}
while(!half_b[half_b[0]])
half_b[0]--;
double_a=val_a*val_a;
if(val_b[1]&1)
{
// ret=(double_a^half_b)*val_a;
BigNum_ temp;
BigNum_power(double_a,half_b,temp);
BigNum_multiply(temp,val_a,ret);
}
else
{
// ret=double_a^half_b;
BigNum_power(double_a,half_b,ret);
}
return;
}
BigNum_ operator^(BigNum_ val_a,BigNum_ val_b)
{
if(val_b[0]==1)
{
if(val_b[1]==0)
return BigNum_1;
if(val_b[1]==1)
return val_a;
}
if(val_a[0]==1)
if(val_a[1]==1||!val_a[1])
return val_a;
BigNum_ half_b,double_a;
int this_dig,next_dig=0;
half_b=val_b;
for(int i=half_b[0];i;i--)
{
this_dig=next_dig;
next_dig=half_b[i]&1?5:0;
half_b[i]=half_b[i]/2+this_dig;
}
while(!half_b[half_b[0]])
half_b[0]--;
double_a=val_a*val_a;
if(val_b[1]&1)
return (double_a^half_b)*val_a;
else
return double_a^half_b;
}
void BigNum_factorial(BigNum_&val,BigNum_&ret)
{
ret=BigNum_1;
for(BigNum_ i={1,1};i<=val;i=i+BigNum_1)
ret=ret*i;
return;
}
void BigNum_resize(BigNum_&ret,int val)
{
reverse(ret.begin(),ret.end());
ret.pop_back();
ret.resize(val);
ret.push_back(val);
reverse(ret.begin(),ret.end());
return;
}
void BigNum_division(BigNum_ val_a,BigNum_&val_b,BigNum_&ret)
{
if(val_a<val_b)
{
ret=BigNum_ {1,0};
return;
}
if(val_b==BigNum_0)
{
ret=BigNum_ERR;
return;
}
ret.clear();
ret.push_back(val_a[0]-val_b[0]+1);
BigNum_resize(ret,ret[0]);
for(int i=val_a[0],ii=val_b[0];i>=ii;i--)
{
BigNum_resize(val_b,i);
while(val_a>=val_b)
{
val_a=val_a-val_b;
ret[i-ii+1]++;
}
}
while(!ret[ret[0]]&&ret[0]>1)
ret[0]--;
ret.resize(ret[0]+1);
return;
}
BigNum_ operator/(BigNum_ val_a,BigNum_ val_b)
{
if(val_a<val_b)
return BigNum_ {1,0};
if(val_b==BigNum_0)
return BigNum_ERR;
BigNum_ ret;
ret.push_back(val_a[0]-val_b[0]+1);
BigNum_resize(ret,ret[0]);
for(int i=val_a[0],ii=val_b[0];i>=ii;i--)
{
BigNum_resize(val_b,i);
while(val_a>=val_b)
{
val_a=val_a-val_b;
ret[i-ii+1]++;
}
}
while(!ret[ret[0]]&&ret[0]>1)
ret[0]--;
ret.resize(ret[0]+1);
return ret;
}
void BigNum_modulo(BigNum_ val_a,BigNum_&val_b,BigNum_&ret)
{
if(val_a<val_b)
{
ret=val_a;
return;
}
if(val_b==BigNum_0)
{
ret=BigNum_ERR;
return;
}
BigNum_resize(ret,ret[0]);
for(int i=val_a[0],ii=val_b[0];i>=ii;i--)
{
BigNum_resize(val_b,i);
while(val_a>=val_b)
val_a=val_a-val_b;
}
ret=val_a;
while(!ret[ret[0]]&&ret[0]>1)
ret[0]--;
ret.resize(ret[0]+1);
return;
}
BigNum_ operator%(BigNum_ val_a,BigNum_ val_b)
{
if(val_a<val_b)
return val_a;
if(val_b==BigNum_0)
return BigNum_ERR;
BigNum_ ret;
for(int i=val_a[0],ii=val_b[0];i>=ii;i--)
{
BigNum_resize(val_b,i);
while(val_a>=val_b)
val_a=val_a-val_b;
}
ret=val_a;
while(!ret[ret[0]]&&ret[0]>1)
ret[0]--;
ret.resize(ret[0]+1);
return ret;
}
BigNum_ BigNum_gcd(BigNum_ val_a,BigNum_ val_b)
{
while(val_a>BigNum_0)
{
swap(val_a,val_b);
val_a=val_a%val_b;
}
return val_b;
}
void BigNum_gcd(BigNum_ val_a,BigNum_ val_b,BigNum_&ret)
{
while(val_a>BigNum_0)
{
swap(val_a,val_b);
val_a=val_a%val_b;
}
ret=val_b;
return;
}
BigNum_ BigNum_lcm(BigNum_ val_a,BigNum_ val_b)
{
return val_a*val_b/BigNum_gcd(val_a,val_b);
}
void BigNum_lcm(BigNum_&val_a,BigNum_&val_b,BigNum_&ret)
{
ret=val_a*val_b/BigNum_gcd(val_a,val_b);
return;
}
}
using namespace BigNum41;
#define putt(x) cout<<#x<<" = "<<(x)<<endl;
#define MAX 100007
const ll MOD = 1000000007; //模数,常用的还有 998244353;
const double eps = 1e-8; //保留6位小数的精度,保留k位小数时一般取1e-(k+2);
map<int,int>dig1_mapp;
inline int dig1() // 一位随机数,0~9
{
int mn=dig1_mapp[0];
for(int i=1;i<=9;i++)
mn=min(mn,dig1_mapp[i]);
for(int i=0;i<=9;i++)
dig1_mapp[i]-=mn;
int ret=(rand()+clock())%10;
while(dig1_mapp[ret]>10) // 设置偏移量,越小越接近平均概率
ret=(rand()+clock())%10;
dig1_mapp[ret]++;
// putt(ret);
return ret;
}
long long rd_ll(int digs=9) // digs表示十进制下的位数
{
long long ret=dig1();
for(int i=1;i<digs;i++)
{
ret=(ret<<3)+(ret<<1)+dig1();
Sleep(dig1());
}
return ret;
}
BigNum_ rd_bn(int digs=9) // digs表示十进制下的位数
{
BigNum_ ret={1,dig1()};
for(int i=1;i<digs;i++)
{
ret=ret*BigNum_trans(10);
ret=ret+BigNum_trans(dig1());
Sleep(dig1());
}
while(ret[0]>1&&ret[ret[0]]==0)
{
ret.pop_back();
ret[0]--;
}
return ret;
}
int main()
{
// ios_base::sync_with_stdio(false);
// cin.tie(nullptr);
// cout.tie(nullptr);
验证一位随机数
// mll mapp;
// while(1)
// {
// int temp=dig1();
// mapp[temp]++;
// ll mn=mapp[0];
// for(ll i=1;i<=9;i++)
// mn=min(mn,mapp[i]);
// for(ll i=0;i<=9;i++)
// mapp[i]-=mn;
// for(ll i=0;i<=9;i++)
// printf("%5lld",mapp[i]);
// printf(" \r");
// }
// return 0;
验证大随机数
// puts("Press any key to continue .");
// while(!kbhit());
// BigNum_ x=rd_bn();
// BigNum_ minn=x,maxx=x;
// BigNum_ minnf(0),maxxf(0);
// while(1)
// {
// x=rd_bn();
// minn=(x<minn?x:minn);
// maxx=(x>maxx?x:maxx);
// // if(minn!=minnf||(maxx!=maxxf))
// {
// --minn;
// putchar('\t');
// --maxx;
// putchar('\t');
// --x;
// printf(" \r");
// minnf=minn;
// maxxf=maxx;
// }
// }
验证随机数
// map<ll,int>mapp;
// int mx=0;
// for(int cas=1;cas;cas++)
// {
// ll temp=rd_ll(3);
// ++mapp[temp];
// if(clock()%1000<40)
// {
// // --temp;
// printf("%lld",temp);
// printf("\t%6d\t%d\t%d\n",cas,mapp[temp],mx=max(mx,mapp[temp]));
// }
// }
return 0;
}
/*
dig1() 一位随机数 int
rd_ll() 多位随机数 long long
rd_bn() 多位随机数 BigNum_
*/