只需从Python切换到C ++,我开始用C ++重新编写我的Python工具以便更好地理解,但无法解决这个问题......
此函数将生成随机数范围,例如“randomRange(12)”可返回12个数字的范围,如“823547896545”
的Python:
def randomRange(n):
range_start = 10**(n-1)
range_end = (10**n)-1
return randint(range_start, range_end)
number = randomRange(12)
C ++:
int n;
int randomRange(n){
int range_start = ?
int range_end = ?
int result = ?(range_start, range_end);
return (result);
};
int number = randomRange(12);
我找不到相应的问号“?”
答案 0 :(得分:4)
使用高n值获得良好的随机性时会遇到问题,但是:
#include <math.h> // for pow()
#include <stdlib.h> // for drand48()
long randomRange(int n)
{
// our method needs start and size of the range rather
// than start and end.
long range_start = pow(10,n-1);
long range_size = pow(10,n)-range_start;
// we expect the rand48 functions to offer more randomness
// than the more-well-known rand() function. drand48()
// gives you a double-precision float in 0.0-1.0, so we
// scale up by range_size and and to the start of the range.
return range_start + long(drand48() * range_size);
};
这是另一种方法。在32位平台上,你只能在一个int中做9位数,所以我们将使函数返回一个double,然后生成一个ASCII数字字符串然后转换:
#include <math.h> // for pow()
#include <stdlib.h> // for atof()
// arbitrary limit
const int MAX_DIGITS = 24;
double randomRange(int n)
{
char bigNumString[ MAX_DIGITS+1 ];
if (n > MAX_DIGITS)
{
return 0;
}
// first digit is 1-9
bigNumString[0] = "123456789"[rand()%9];
for (int i = 1; i < n; i++)
{
// subsequent digits can be zero
bigNumString[i] = "0123456789"[rand()%10];
}
// terminate the string
bigNumString[i] = 0;
// convert it to float
return atof(bigNumString);
};
答案 1 :(得分:2)
你应该看一下boost中的设施:
C ++ 11中也有类似的功能:
http://en.cppreference.com/w/cpp/numeric/random
int randomRange(n)
{
int range_start = (int)pow(10, n-1);
int range_end = (int)pow(10, n) - 1;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(range_start, range_end);
return dist(gen);
}
请注意,通过将dist(gen)
之外的所有内容移动到仅调用一次的初始化函数,可以获得更好的性能。
答案 2 :(得分:1)
你基本上只有rand,你可以屈服于你的意愿:
int result = (rand() % (range_end - range_start)) + range_start;
为了解释,rand()在整数值的子集上生成一个随机数。您可以使用modulo lo限制数字的范围,然后使用起始值来提供偏移量。
(还要确保seed the random number generator)
注意强> 兰德显然是一个非常糟糕的随机数发生器(我不知道)。见评论。
答案 3 :(得分:0)
答案 4 :(得分:0)
我会使用类似的东西:
#include <ctime>
#include <cmath>
unsigned long long randomRange(unsigned int n){
static bool first = true;
if (first)
srand((unsigned int)time(nullptr)); //seed the generator the first time
//as others say, std::pow to get the range
double range_start = std::pow(10.0, n-1.0);
double range_end = std::pow(10.0, double(n))-1.0;
unsigned long long range = range_end-range_start;
//generate a random number between 0 and 2^64 (minimum)
unsigned long long result
= rand()*RAND_MAX*RAND_MAX*RAND_MAX
+ rand()*RAND_MAX*RAND_MAX
+ rand()*RAND_MAX
+ rand();
//force it into range.
return unsigned long long(result % range + range_start);
};
unsigned long long number = randomRange(12);
这很简单,(我一直使用这样的东西),但是rand()不是最均匀的分布,并且在最后一步中使用modulo会使结果偏向更低的数字。此外,由于它调用rand()四次次,它可能比许多解决方案慢,并且由于我对RAND_MAX做了最小的假设,它可能不是最佳的(尽管如此。但是,这是一个简单的解决方案这是可移植的。(适用于windows / linux /无论如何),只要n在1到17之间就可以工作。在17以上,它只会选择范围底部的数字,但是因为64位长无论如何,长期只保留~19.26位数,我认为这不是一个问题。