我正在研究一个同义词拼图,它会给你一个单词,并希望你找到它的同义词给出单词的长度。一切正常,但它发生在一个有序的序列上;单词不会随机出现。我需要k
个非重复随机数。这是我的代码:
#include<iostream>
#include<string>
#include<cstdlib>
#include<ctime>
using namespace std;
int main()
{
const int k=4;
string word[k]={"furious","tiny","untrue", "humorous", "harm"};
string nword[k]={"angry","small","false", "funny", "damage"};
string j;
int point, p = 0;
int ctr=0;
srand(time(NULL));
int randNum = (rand() % k) + 0;
for(int i=0; i<k; i++)
{
cout << nword[i] << "\n";
cout << "The length of the word: " << word[i].length() << "\n";
cin>>j;
ctr++;
if(j==word[i])
{
cout<<"Correct! Score: " << i+1 << " point." << "\n\n";
}
else
{
cout<<"Wrong"<<endl;
}
}
return 0;
}
如您所见,变量randNum
保存从0到k的随机数的值,(k为4,结合0,我有5个单词)。在for循环中,当我设置像nword[randNum]
和word[randNum]
这样的nword和word时,结果会留下很多不足之处。首先,我认为两者(nword和word)没有同步。它将为两者应用不同的随机数(我可能是错的),第二,它将是重复的。如图所示,执行是基于分数和可完成的,因此我需要不重复的问题,直到它达到k
。
答案 0 :(得分:2)
您可以使用Durstenfeld shuffle:
来改变您的单词数组for(int i=k-1; i>0; i--)
{
int j = rand() % (i+1)
string temp = word[i];
word[i] = word[j];
word[j] = temp;
temp = nword[i];
nword[i] = nword[j];
nword[j] = temp;
}
正如WhozCraig所指出的,另一种选择(可以说更好,因为它不需要置换多个数组),就是创建一个索引为0 ...(k-1)的数组,然后改组这个数组。然后,该数组将包含一组随机索引,可用于迭代单词数组。
#include <iostream>
#include <algorithm>
#include <string>
#include <random>
#include <numeric>
using namespace std;
int main()
{
static const size_t k=5;
string word[k]={"furious","tiny","untrue", "humorous", "harm"};
string nword[k]={"angry","small","false", "funny", "damage"};
int ctr=0;
// build prng
std::random_device rd;
std::mt19937 rng(rd());
// build index sequence, then shuffle
size_t idx[k];
std::iota(std::begin(idx), std::end(idx), 0);
std::shuffle(std::begin(idx), std::end(idx), rng);
for(auto i : idx)
{
std::string s;
cout << nword[i] << "\n";
cout << "The length of the word: " << word[i].length() << "\n";
if (!(cin>>s))
break;
if(s==word[i])
{
cout<<"Correct! ";
++ctr;
}
else
{
cout<<"Wrong. ";
}
std::cout << "Score: " << ctr << " point(s).\n\n";
}
return 0;
}