非重复随机数

时间:2016-07-07 06:06:52

标签: c++ random

我正在研究一个同义词拼图,它会给你一个单词,并希望你找到它的同义词给出单词的长度。一切正常,但它发生在一个有序的序列上;单词不会随机出现。我需要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

1 个答案:

答案 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;
}