c ++随机数重复防止

时间:2017-01-05 17:28:11

标签: c++

我有一个随机数生成器功能(" Rndom(min,max)"), 我有一个带有4个元素的int,名为" Data [3]"。 我使用for循环生成数字(1-4)到"数据"的元素。 INT:

for (int i = 0;i < 3;i++)
{
    Data[i] = Rndom(1, 4)
}

如何防止数据获得重复的元素编号? 所以,我不想要这个:&#34;数据&#34;要素:1 3 4 1(&#34; 1&#34;重复)。我想提出不同的数字......

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

由于你需要一个混洗整数值的数组或向量,使用std::shuffle来混淆用连续值初始化的向量(或其他)。

#include <iostream>
#include <vector>
#include <random>
#include <algorithm>
#include <numeric>

int main() {
    std::random_device rd;
    std::mt19937 rng(rd());                       // seed rng using rd
    std::vector<int> data(3);                     // create a 3-entry vector
    std::iota(data.begin(), data.end(), 0);       // fill with sequence
    std::shuffle(data.begin(), data.end(), rng);  // mix entries using rng
    // dump the result
    for(auto r : data) { std::cout << r << ' '; }
    std::cout << '\n';
}

3次执行的输出:

1 0 2

2 1 0

2 0 1

这是一个不太依赖标准C ++库的版本,并且使用C-runtime蹩脚的随机数生成器,因为我无法访问Rndom的源代码,这无疑是专有的大自然,所以这是可以理解的:

#include <iostream>  // only for std::cout
#include <cstdlib>   // for srand, rand
#include <ctime>     // for time

namespace shuffle {
    using size_t = decltype(sizeof(1));

    bool Srndom() {
        std::srand(std::time(0));
        return true;
    }

    int Rndom(int low, int high) {
        static bool init = Srndom();
        return std::rand() % (high - low + 1) + low;
    }

    template <typename T>
    void Shuffle(T* pdata, size_t N) {
        for(size_t i=0; i<N-1; ++i) {
            const int swap_idx = Rndom(i, N-1);
            if(swap_idx != i) {
                const T t = pdata[i];
                pdata[i] = pdata[swap_idx];
                pdata[swap_idx] = t;
            }
        }
    }

    template <typename T, size_t N>
    void Shuffle(T (&data)[N]) {
        Shuffle(data, N);
    }

    template <typename T>
    void Series(T* pdata, size_t N, T start) {
        for(size_t i=0; i<N; ++i) {
            pdata[i] = start++;
        }
    }

    template <typename T, size_t N>
    void Series(T (&data)[N], T start) {
        Series(data, N, start);
    }
}

int main() {
    using namespace shuffle;

    int Data[4];     // I guess you actually want 4
    Series(Data, 1); // and maybe to start at 1.
    Shuffle(Data);   // Shuffle Data's entries.

    // Dump Data's entries
    for(size_t i=0; i<sizeof(Data)/sizeof(Data[0]); ++i) {
        std::cout << Data[i] << ' ';
    }
    std::cout << '\n';
}

3次执行的输出(相隔超过1秒):

2 3 1 4

4 2 3 1

2 4 3 1

答案 1 :(得分:1)

使用mapset存储生成的数字,避免重复。

set<int> s;
for (int i = 0;i < 3;i++)
{
   int x;
   for(;;)
   {
      int x = Rndom(1, 4) ;

      if(s.find(x)==s.end()) 
      {
         s.insert(x);
         Data[i]=x;
         // consider it ..it is not duplicate
         break;
      }
   }
}

您也可以使用setunordered_set来实现同样的目标。

使用set而非map的原因是std::sets仅包含密钥,而在std::map中则存在关联值。