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

时间:2014-08-29 02:00:33

标签: c++ shuffle visual-c++-2010

#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开始)。另外,我如何防止数字相互重叠?也就是说,如果我从1-39输出5个不同的数字,它总是可以有5个不同的数字,如4,5,2,7,12而不是4,5,2,4,12(4在这里使用两次)< / p>

4 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

  

无规=(RAND()%39)1;

这可能导致重复。


  

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

范围[begin,end](括号中的含义为“包含”)的元素数量为:

 count = end - begin + 1

如果你需要一个基于0的count元素,那么你执行:

rand() % count

因为起始元素可能为0,所以实际执行以下操作以获取范围内的值:

rand() % count + begin

  

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

在这种情况下,更简单的解决方案之一是使用矢量。它没有其他答案那么有效(就像@Retired Ninja建议的那样),但它更容易理解。如下所示:

下面的代码只是转储shuffle的结果(这不是随机的,因为它会根据使用的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 ),那么你将不需要{{1} }。 Visual Studio将破坏并等待您。检查完值后,按 F5 完成程序。

答案 3 :(得分:1)

尝试创建一个包含数字1 -39的向量,将它们随机播放,然后选择第一个5.然后你有5个非重复的随机数。

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