2014-09-27 171 views
1

我已经用3个随机整数编码了一个数组。关键是虽然我希望3个随机整数不同于彼此(唯一的随机数)。我的问题是,即使数字是独一无二的,我仍然从他们那里得到一个“不好的”读数。随着时间的推移,我随机播放了数字(NULL),正因为如此,我在每个声明之间放置了一个Sleep(x)函数以增加数字的多样性。以下代码是我的main()函数中的所有代码。出于测试目的,我没有在我的代码中包含break语句,所以我可以一遍又一遍地测试程序。在数组中生成唯一的随机数C++

srand((unsigned)time(NULL)); 

while(true) 
{ 
    //Generate 3 numbers 
    int a = rand() % 7 + 1; 
    Sleep(1000); 
    int b = rand() % 8 + 1; 
    Sleep(1000); 
    int c = rand() % 9 + 1; 
    int array[3] = { a , b , c }; 

    //Check the numbers to make sure none of them equal each other 
    if((array[a] == array[b]) || (array[a] == array[c]) || (array[b] == array[c])) 
    { 
     //Print all numbers 
     for(int x = 0; x < 3; x++) 
      cout << array[x] << endl; 
     cout << "bad" << endl; 
     system("pause"); 
     system("cls"); 
    } 
    else 
    { 
     //Print all numbers 
     for(int x = 0; x < 3; x++) 
      cout << array[x] << endl; 
     cout << "good" << endl; 
     system("pause"); 
     system("cls"); 
    } 
} 
system("pause"); 
return 0; 
+4

'睡眠'调用不会改变生成的数字。只有'srand(time(NULL))'运行时才会检查时间。 – programmerjake 2014-09-27 00:09:20

+1

请注意,对'srand'的调用是随机数生成器的种子。每次调用'rand'时都不会使用单独的种子。所以,睡眠是没有意义的。 – Pradhan 2014-09-27 00:09:30

+0

要生成唯一的数字,对于相对较小的固定集合,最简单/可靠的方法之一是创建一个* allowed *值的数组,然后对数组进行随机洗牌并获取前N个值。例如,给定一个数组{1,2,3,4,5,6,7,8,9},然后使用arr [0],arr [1],arr [2]等。有很多问题/适合并推荐这种(Fisher-Yates)混洗方法的答案。 – user2864740 2014-09-27 00:15:22

回答

5

与当前检查的问题是它会检查在索引由随机值来表示的,而不是随机值本身,这是第一个3个元素。

只需更换

if((array[a] == array[b]) || (array[a] == array[c]) || (array[b] == array[c])) 

if((array[0] == array[1]) || (array[0] == array[2]) || (array[1] == array[2])) 

或只是

if(a == b || a == c || b == c) 
+0

(请务必添加书面说明。) – user2864740 2014-09-27 00:21:15

0

看来你使用Sleep,这无关与Windows的特定功能C库。 srand会影响rand()返回的序列,如果srand()被赋予相同的种子,则该序列是可重复的。

其次,随机数即要存储在abc范围可可能导致出界数组访问在这条线的位置:

if((array[a] == array[b]) || (array[a] == array[c]) || (array[b] == array[c])) 

array只有3个元件,但这些值在a,bc可以高于那个。

由于您使用的是C++,因此请考虑利用C++标准库。

首先创建一个指定大小的向量,并使用std::iota来填充范围为[0,10)的值。

std::vector<int> v(10); 
std::iota(v.begin(), v.end(), 0); 

然后,我们使用std::random_shuffle来重新排序数值。

std::random_shuffle (v.begin(), v.end()); 

,并挑选前三个值:

for (int i = 0; i < 3; ++i) 
    std::cout << v[i] << " "; 
+0

这是非常有趣的代码。它吸引我。我只有1个问题。当你说“挑选前三个数值”时,你的意思是排在前面的前3个数或最大数? – user3742063 2014-09-27 20:35:17

+0

@ user3742063第一个。 – 2014-09-27 22:41:55

0
  1. 像其他人一样说,该睡觉什么也不做。
  2. 洗牌的想法不是很好。它比重新生成数字要慢,直到你获得唯一的数字,并且它不能很好地扩展。如果你希望允许的数字范围很大,洗牌将变得非常昂贵。

我会做这样的事情:

int a = rand() % 7 + 1; 

int b = rand() % 8 + 1; 
while(a == b) 
    b = rand() % 8 + 1; 

int c = rand() % 9 + 1; 
while((a == c) || (b == c)) 
    c = rand() % 9 + 1; 

int array[3] = { a , b , c }; 
  • 您的 “坏值” 检查应该是:

    IF((A == b)||(a == c)||(b == c))

  • +0

    优胜者优胜者鸡晚餐!我不知道为什么我没有想到这一点。非常感谢你。 – user3742063 2014-09-27 20:36:06