如何在C++中生成的随机数应用程序中使数字不重复

How to make numbers not repeated in a random number generated app in C++?

本文关键字:数字 应用程序 随机数 C++      更新时间:2023-10-16

我有一个应用程序可以显示乐透最大值,我需要让我的应用程序生成随机数字,但我需要数字不要重复。我已经完成了我的代码,并希望尽可能地进行一些更改。但任何帮助都会很棒!

    #include <iostream> 
    #include <iomanip>
    #include <cstdlib>
    using namespace std;
    int main()
    {
    {
cout << "*** LOTTO  MAX  INSTA  PICK ***" << endl;
cout<< " " << endl << endl;
    }
     {
 cout << "Your Insta Pick Numbers" << endl;
 cout<< " " << endl << endl;
     }
 for (int counter = 1; counter <= 21; ++ counter)
{
cout << setw(1) << (1 + rand() % 49) << " ";

if (counter % 7 == 0)
        cout << endl;
}
{
    cout<< " " << endl << endl;
}

{
cout << "Your Tag Numbers" << endl;
cout<< " " << endl << endl;
    }
for (int counter = 1; counter <= 9; ++ counter)
{
cout << setw(1) << (0 + rand() % 9)<< " ";

if (counter % 9 == 0)
        cout << endl;
}
{
    cout<< " " << endl << endl;
}
{
    cout << "Thank you for playing!! please check ticketn a year minus a day            from date of purchase" <<endl;
}
    };

如果这是一个家庭作业,我不会发布完整的解决方案。

但是,作为一个建议,您可以将已经提取的数字存储在某个位置(例如,在排序的[*]std::vectorstd::map中),然后,当您提取新数字时,您可以检查该数字是否已经存在于容器中。如果是,则尝试提取一个新号码,直到在容器中找不到提取的号码为止。

[*]矢量是排序的,这一事实允许快速的二进制搜索(我不知道你要加多少数字;如果这个计数很低,那么简单的O(N)线性搜索就可以了;对于更大的计数,O(log(N))二进制搜索提供更好的性能)。

在使用rand函数之前,您需要为生成器设定一个唯一的值。这是通过srand函数完成的。通常,唯一编号是time:返回的当前时间

srand(time(0));

除非您能够在一秒钟内多次运行应用程序,否则每次运行应用程序时,结果都是唯一的。

您需要一个数据结构来存储已经绘制的数字。当你生成一个数字时,你会在数据结构中查找它,如果它已经存在,你会重新绘制,否则,你会添加数字。CCD_ 6是一种合适的数据结构。

我会填充一个向量来选择数字,并将该向量中选择的数字替换为最后一个数字,这样每次选择都保证得到一个唯一的数字。

基本上,当我们使用任何rand函数时,它都不会认为它总是会生成一个唯一的数字。因此,只有一种解决方案可以使数据结构(如数组)存储随机数,并用数组检查新装入的随机数。如果存在,则再次调用您的随机生成函数。

假设您的应用程序将返回49个数字中的一个,让我们存储所有可能的数字:

int numbers[49];

初始化它们:

for( int i = 0; i < 49; i++){
    numbers[i] = i+1;
}

存储您可以获得的最大数量:

int max = 49;

现在的猜测算法:

int index = rand()%max; // Get just number inside the boundaries
int result = numbers[index]; // Store the number
max--; // Decrease maximum number you can get
numbers[index] = numbers[max]; // Move last number to place of just guessed number
numbers[max] = 0; // Erase last number

里面发生了什么(5个数字):

  • 假设你有这5个数字:[1 2 3 4 5]
  • rand()%5将输出2,即numbers[2],即数字3(结果)
  • 我们不能再使用3了,但我们可以使用数字5并将列表缩短1,所以将5移到第三位,这样您的数组就会看起来像:[1 2 5 4 5]
  • 从末尾删除5 [1 2 5 4 0]
  • 减小最大值,所以我们猜测只有索引0-3,数组似乎是[1 2 5 4]

个人注意:你也可以使用std::容器,但这就像用火焰喷射器猎杀苍蝇

如果您使用gcc,您可以利用一些库来生成数字容器,对它们进行加扰,然后从容器中弹出数字,一次一个:

#include <algorithm>
#include <ext/numeric>
#include <vector>
#include <iostream>

int main(int argc,const char** argv)
{
  std::vector<int>  v(21);
  __gnu_cxx::iota(v.begin(),v.end(),0);
  std::random_shuffle(v.begin(),v.end());
  while( !v.empty() ) {
    std::cout << v.back() << std::endl;
    v.pop_back();
  }
  return( 0 );
}

如果您不使用gcc,iota可能在命名空间std.

中的"numeric"(而不是"ext/number")中