如何在不使数字重叠的情况下生成 1 - 39 的随机数

How can I generate a random number from 1 - 39 without making a number overlap?

本文关键字:随机数 情况下 数字 重叠      更新时间:2023-10-16
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void randnum()
{
    int random;
    srand((unsigned int)time(0));
    for(int i=1;i<=5;i++)
    {
        random=(rand()%39)+1;
        cout<<random<<endl;
    }
}
int main()
{
    cout<<"Five random number is here"<<endl;
    randnum();
    system ("PAUSE");
    return 0;
}

我随机这样做是为了练习C++。我总是在设置随机生成器的范围时感到困惑(我的方法正确吗?从 1-39(。另外,如何防止数字相互重叠?也就是说,如果我从 5-1 输出 39 个不同的数字,它总是可以 5 个不同的数字,例如 4,5,2,7,12 而不是 4,5,2,4,12(这里使用 4 两次(

是的,获取 1 到 39 之间的随机数的方法是正确的。

为了确保数字不重叠,我想到了两种算法:

  1. 保留一组已经投放的号码,并在第二次选择时跳过,或者
  2. 创建所有候选人编号的列表并随机重新排序,然后按顺序提供服务

该方法是正确的。为了防止数字相互重叠,对我来说,最好的解决方案是创建一个已经生成的数字的向量,每次生成新的随机数时,看看它是否已经在向量中。如果是,请再生。如果不是,则将其添加到向量中并继续。

尝试创建一个包含数字 1 -39 的向量,将它们洗牌,然后选择前 5 个。那么你有 5 个非重复的随机数。

random_shuffle(( 函数在C++库中实现。在这里查看:http://www.cplusplus.com/reference/algorithm/random_shuffle/

随机=(rand((%39(+1;

这可能会导致重复。


总是在设置随机生成器的范围时感到困惑(我的方法从 1-39 是否正确?

范围 [begin,end](其中括号表示"包含"(中的元素数为:

 count = end - begin + 1

如果您需要从 0 开始的 count 元素之一,则执行:

rand() % count

由于起始元素可能不是 0,因此您实际上执行以下操作以获取范围内的值:

rand() % count + begin

另外,如何防止数字相互重叠?

在这种情况下,更简单的解决方案之一是使用向量。它不像其他答案(如@Retired忍者建议的答案(那样有效,但它更容易理解。如下所示。

下面的代码只是转储随机播放的结果(这不是随机的,因为它会根据所使用的seed在运行中重复(。您应该不难将其适应前 5 个元素(我们无法为您提供所有答案(。

ShuffledRange range (1, 39);
...
$ ./tt.exe 
29 33 8 37 9 32 38 24 16 14 36 7 10 31 34 39 27 11 6 4 35 1 19 20 18 15 5 12 22
21 3 30 17 25 2 28 23 26 13 

如果指定seed(默认值为 0(,则将获得不同的序列:

ShuffledRange range (1, 39, 2);
...
$ ./tt.exe 
12 20 28 6 7 15 32 17 35 11 18 31 27 4 23 36 25 24 22 1 33 2 37 39 21 9 38 13 5 3
14 10 8 34 16 19 29 26 30

由于random_shuffle,下面的代码需要C++ 11 。Visual Studio 2012 应该可以与 C++ 11 一起使用。我不确定Visual Studio 2010。

海湾合作委员会将需要:

$ g++ -Wall -Wextra -std=c++11 tt.cpp -o tt.exe

和 Mac OS X:

$ g++ -Wall -Wextra -std=c++11 -stdlib=libc++ tt.cpp -o tt.exe

class ShuffledRange
{
public:
    explicit ShuffledRange(unsigned int low, unsigned int high, int seed=0)
      : m_numbers(move(create_numbers(low,high,seed))), m_it(m_numbers.begin()) { }
    unsigned int GetCount() const {
        return static_cast<unsigned int>(m_numbers.size());
    }
    bool HasNext() const {
        return m_it != m_numbers.end();
    }
    unsigned int GetNext()
    {
        if(!HasNext())
            throw std::runtime_error("No numbers left");
        unsigned int temp = *m_it++;
        return temp;
    }
protected:                
    vector<unsigned int> create_numbers(unsigned int low, unsigned int high, int seed)
    {
        if(high < low)
            throw std::runtime_error("Bad range of elements");
        vector<unsigned int> temp;
        temp.reserve(high - low + 1);
        for(unsigned int i = low; i <= high; i++)
            temp.push_back(i);
        srand(seed);
        random_shuffle(temp.begin(), temp.end());
        return temp;
    }
private:
    vector<unsigned int> m_numbers;
    vector<unsigned int>::iterator m_it;
};
int main(int argc, char* argv[])
{
    ShuffledRange range(1, 39);
    while(range.HasNext())
        cout << range.GetNext() << " ";
    cout << endl;
    return 0;
}

提示....

int main()
{
    cout<<"Five random number is here"<<endl;
    randnum();
    system ("PAUSE");
    return 0;
}

如果在main的右大括号(即}(上放置断点(F9(,则不需要system ("PAUSE");。Visual Studio会休息并等待你。检查值后,按 F5 完成程序。