将唯一的随机数插入到一个向量中

问题描述:

作为某个游戏的代码的一部分,我想生成4个唯一的随机数到一个向量中。将唯一的随机数插入到一个向量中

此代码适用于某些重复播放次数,然后应用程序崩溃(无响应窗口)。

虽然我了解if-condition可以防止for-loop将相同的数字插入到vector中,但是这个for-loop需要多少时间才能通过rand()函数生成唯一的数字? srand(time(NULL))rand()如何根据系统时间一起创建随机值?

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <cstdlib> 
#include <ctime> 

using namespace std; 

//plays bulls and cows 


int main() { 
srand(time(NULL)); 
string play="yes"; 
int nums=4;  // number of values in an answer (must NOT exceed 10) 
vector<int> answer; 


while (play=="yes" || play=="YES" || play=="Y" || play=="Yes" || play=="y") { //plays the game 

answer.push_back(rand()%10+1); 
    do {        //fills vector with unique random numbers 
    for (int i=1; i<nums; i++) { 
     answer.push_back(rand()%10+1); 
     if (answer[i]==answer[i-1]) { 
     i=i-1; 
     continue; 
     } 
     } 
    } while (answer.size()!=nums); 

for (int i=0; i<nums; i++) { 
    cout<<answer[i]; 
} 

    cout<<"Do you want to play again?"<<'\n'; 
    cin>>play; 
    answer.clear(); 
} //game ends 


if (play=="no" || play=="n" || play=="No" || play=="NO" || play=="N") { //terminates and checks for exceptions 
    cout<<"Thank you for playing!"<<'\n'; 
    return 0; 
} else { 
    cerr<<"Error: wrong input. Terminating."<<'\n'; 
    return 0; 
} 

    return 0; //safety return 
} 
+0

另外,我知道有更好,C++ 11的方式要做到这一点,但我需要这样做。 – bruneleski

+0

考虑使用'std :: set'而不是'std :: vector'。一组只存储唯一值:'std :: set answer; while(answer.size() PaulMcKenzie

+0

这很酷。但我们现在使用矢量,所以不知道他们是否会接受设置。 (练习某种东西) – bruneleski

问题是你总是推回你的向量中的随机值,然后检查它是否有效。比方说,你的程序才能产生这些随机值:

2,6,6,7,9,10

会发生什么事是你将插入2(我== 2),6(我== 3 ),6(i == 4),然后实现6重复两次,所以你回去一次迭代(i == 3),但你的六个都仍然在你的向量。所以现在你将添加7(i == 4),你将退出for循环,在你的矢量中有5个值。

然后,当您评估您的do-while条件时,您的answer.size()将永远不会等于4,因为它已经等于5.您现在陷入无限循环,并且您的应用程序在消耗时崩溃你矢量中的所有可用内存无限增长。

此外,您的逻辑似乎有错误。为了确保你没有重复的值(并且你被向量卡住了),你不应该只验证最后插入的值,而是整个向量。就像这样:

#include <algorithm> 

if (std::find(vector.begin(), vector.end(), item) != vector.end()) 
    do_this(); 
else 
    do that(); 

为什么您将新尝试添加到answer而不是临时变量。如果变量有效,则将其添加到答案中。在你的情况下,i始终保持在1;

while (play=="yes" || play=="YES" || play=="Y" || play=="Yes" || play=="y") { //plays the game 

    int last_try=rand()%10+1; 
    answer.push_back(last_try); 
    do { //fills vector with unique random numbers 
      int new_try=rand()%10+1; 

      if (last_try!=new_try) 
      { 
       answer.push_back(new_try); 
       last_try=new_try; 
      } 
    } while (answer.size()!=nums); 


    for (int i=0; i<nums; i++) 
    { 
     cout<<answer[i]<<"\n"; 
    } 

    cout<<"Do you want to play again?"<<'\n'; 
    cin>>play; 
    answer.clear(); 
} //game ends 
+0

这比我的东西更合理。谢谢。 但是核心思想不一样吗? 我的意思是它发生在某种程度上bruteforces for-loop,因为如果我尝试着不做do-while循环,srand()和rand()总是返回相同的整数。 – bruneleski

+0

@bruneleski,这是真的。这个想法是蛮力。你以前的代码非常脆弱。你有一个for循环for(int i = 1; i jeremine

+0

好吧,我以为我照顾了answer.clear() – bruneleski

假设您必须使用std::vector(而不是std::set)。用随机数填充矢量最简单的方法是检查数字是否已经“看到” - 如果没有,则将其添加到矢量中。

这可以通过使用的bool阵列作为辅助以确定该号码已经看到来完成:

#include <vector> 
#include <iostream> 
#include <cstdlib> 

int main() 
{ 
    std::vector<int> answer; 
    int num = 4; 

    // 10 numbers 
    bool seen[10] = {false}; 

    // keeps track of numbers added 
    int numsAdded = 0; 
    while (numsAdded < num) 
    { 
     int numRand = rand()%10; 
     if (!seen[numRand]) 
     { 
     // not seen, so add it to vector and update bool array and 
     // numsAdded 
     answer.push_back(numRand + 1); 
     seen[num] = true; 
     ++numsAdded; 
     } 
    } 
    for (size_t i = 0; i < num; ++i) 
     std::cout << answer[i] << " "; 
} 

Live Example