将唯一的随机数插入到一个向量中
作为某个游戏的代码的一部分,我想生成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
}
问题是你总是推回你的向量中的随机值,然后检查它是否有效。比方说,你的程序才能产生这些随机值:
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
这比我的东西更合理。谢谢。 但是核心思想不一样吗? 我的意思是它发生在某种程度上bruteforces for-loop,因为如果我尝试着不做do-while循环,srand()和rand()总是返回相同的整数。 – bruneleski
@bruneleski,这是真的。这个想法是蛮力。你以前的代码非常脆弱。你有一个for循环for(int i = 1; i
好吧,我以为我照顾了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] << " ";
}
另外,我知道有更好,C++ 11的方式要做到这一点,但我需要这样做。 – bruneleski
考虑使用'std :: set'而不是'std :: vector'。一组只存储唯一值:'std :: set answer; while(answer.size()
PaulMcKenzie
这很酷。但我们现在使用矢量,所以不知道他们是否会接受设置。 (练习某种东西) – bruneleski