【问题标题】:Random Number generator with range? C++具有范围的随机数生成器? C++
【发布时间】:2019-08-06 12:24:25
【问题描述】:

我正在尝试为我的 Ebay 业务制作一个 15 位数长的 C++ 程序,但我希望前 5 位数相同。

例如:152328476529876 PIN:1000 152323123642345 PIN:9433 152321254213432 PIN:3222

我尝试制作一个随机数生成器,但我无法让它前 5 位数字相同,但后 10 位数字相同。用随机别针。

#include <iostream>
#include <cstdlib> 
const int maximum_number = 9999999999;
const int minimum_number = 1;
unsigned int i;
const int maximum_pin = 999;
const int minimum_pin = 0;
unsigned int pin;
int main()
{

    // Print 100 random numbers
    for (int count = 0; count <= 1000; ++count)
    {
        const int new_number = (rand() % (maximum_number - minimum_number)) + maximum_number;
        const int new_pin = (rand() % (maximum_pin - minimum_pin)) + maximum_pin;
        std::cout << "15232" << new_number << " Pin : "<< new_pin << "\n";
    }

    return 0;
152321410094708 Pin : 1384

152321410073128 Pin : 1567 etc

我遇到的问题是前 5 个数字是相同的,这就是我想要的,但是 14100 保持不变,也应该随机化,而不仅仅是最后 5 个数字......

加上引脚只停留在 1000,它们永远不会超过 1999 等等。

【问题讨论】:

标签: c++ random numbers generator


【解决方案1】:

您应该使用 C++11 中的 &lt;random&gt; 标头,而不是使用 rand() 和模运算。使用来自 n3847 的 Walter E. Brown 的函数工具包,您可以使用:

#include <cstdint>
#include <iostream>
#include <iomanip>
#include <random>

const uint64_t maximum_number = 9999999999;
const uint64_t minimum_number = 1;
const uint64_t maximum_pin = 9999;
const uint64_t minimum_pin = 0;
const uint64_t prefix = 15232;

auto& global_urbg() {
    static std::default_random_engine u{};
    return u;
}

void randomize() {
    static std::random_device rd{};
    global_urbg().seed(rd());
}

uint64_t pick_a_number(uint64_t from, uint64_t thru) {
    static std::uniform_int_distribution<uint64_t> d{};
    using parm_t = decltype(d)::param_type;
    return d(global_urbg(), parm_t{from, thru});
}

int main() {
    randomize();
    for (int count = 0; count < 100; ++count) {
        const uint64_t new_number = pick_a_number(minimum_number, maximum_number);
        const uint64_t new_pin = pick_a_number(minimum_pin, maximum_pin);
        std::cout << prefix << std::setw(10) << std::setfill('0') << new_number
                  << " Pin : " << std::setw(4) << std::setfill('0') << new_pin << "\n";
    }

    return 0;
}

样本输出:

152325021252553 Pin : 1766
152327824160815 Pin : 7717
152321697896629 Pin : 3659
152320879192254 Pin : 8832
152325057425972 Pin : 2831
152323353939394 Pin : 1681
152324684928448 Pin : 9800
152328117866049 Pin : 4173
152326884989008 Pin : 4663
152320007759205 Pin : 7264
152327718061191 Pin : 3968
152322605655403 Pin : 8213
152324442390907 Pin : 7916
152322386351545 Pin : 4683
152321687805442 Pin : 3886
152328171047426 Pin : 6344
152327001747780 Pin : 2636
152325373164268 Pin : 3676

【讨论】:

  • @michael 欢迎您。另请查看 n3847 的其余部分,我刚刚为其添加了链接。
【解决方案2】:

您的问题是,使用 rand() 生成一个随机数会给您一个介于 0 和至少 32767 之间的数字(取决于您的平台,请参阅here),而这个数字不够大。另一个问题是数据类型int 没有足够的位来存储这么大的数字。

这都非常依赖于平台,但这些是最小尺寸:

  • int 使用至少 16 位,可以存储从 0 到 65536 的数字(如果无符号)
  • long 使用至少 32 位,可以存储从 0 到 4294967296 的数字(无符号)
  • long long 使用至少 64 位,可以存储从 0 到 18446744073709551616 的数字(如果无符号)

因此,您的最大值已经存在问题,因为它们不适合 int。如果您想确定您的数字有多大,您可以使用stdint.h 并指定您的intsuint64int32 等。

你想要的是 10 个随机数字。这可以通过以下方式实现:

for (int count = 0; count < 1000; count++) {
    // leading number must not be 0
    long long randomNumber = (rand() % 9) + 1;

    for (int i = 0; i<9; i++) {
        randomNumber *= 10;
        randomNumber += rand() % 10;
    }
    std::cout << "15232" << new_number << "\n";
}

我认为 Pin 有类似的问题

【讨论】:

  • 这比我的好!谢谢!我唯一的问题是有些数字只有 8 位而不是 10 位。
  • 哦,我忘了,如果前导数字为 0,则该数字将被截断 -> 0034 -> 34。一个简单的解决方案是添加一个前导非零数字。但由于 0 不再可能,因此数字会少一些。我在上面添加了它,但如果你想有前导 0,你应该使用一个字符串(char 数组)。
  • 建议不要使用模数,因为它会在生成的随机数分布中引入偏差,例如stackoverflow.com/questions/10984974/…
  • 是的,你是对的!但由于这与安全无关,而且他无论如何都需要检查重复项,这对于这个目的应该没问题。
  • @YannDroneaud -- 虽然这在理论上是正确的,但实际上偏差对于小范围来说是微不足道的。如果RAND_MAX 是32727(这是允许的最小值;许多RNG 的范围要大得多),使用%9%10 将引入大约3000 分之一的偏差,即~.03%。
猜你喜欢
  • 2017-06-05
  • 2013-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 2015-08-18
  • 1970-01-01
相关资源
最近更新 更多