【问题标题】:c++ random number duplicate prevent [duplicate]c++随机数重复防止[重复]
【发布时间】:2017-05-20 08:33:47
【问题描述】:

我有一个随机数生成器函数(“Rndom (min, max)”), 我有一个包含 4 个元素的 int,称为“Data [3]”。 我使用 for 循环为“Data” int 的元素生成数字 (1-4):

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

如何防止数据重复元素编号? 所以,我不想要这个:“数据”元素:1 3 4 1(“1”是重复的)。我想做不同的数字....

感谢您的帮助!

【问题讨论】:

  • 您可以将所有数字放在一个向量中并进行随机播放。这里的例子表明:en.cppreference.com/w/cpp/algorithm/random_shuffle
  • 您的数组是否总是与数字范围的大小相同?
  • 离题:Data [3] 不会包含 4 个元素。
  • Data [0] 也是一个元素......
  • Data [0] 也是一个元素 正确,Data [1] 和 Data [2] 也是如此,但 Data [3] 不是超出范围。所以你只有 3 个元素。

标签: c++


【解决方案1】:

由于您想要一个经过洗牌的整数值的数组或向量,请使用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

【讨论】:

  • 大声笑你没有使用我的功能.....兄弟,这不是一个windows程序......我正在编写一个游戏,它没有像“包含矢量”这样的东西。 ……等等。”
  • 哈哈,你真有趣。但我会继续用我对Rndom 实现和静态分配数组的最佳猜测,用你想要的答案来幽默你。等等……
  • 我正在编写一个没有“包含矢量....等”之类的游戏。您将您的问题标记为c++。 std::vector 是c++ 中标准库的一部分。
【解决方案2】:

使用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 中则有关联的值。

【讨论】:

  • @HolyBlackCat.:实际上我想到了一些不同的东西,这就是我这样回答的原因,无论如何我只是想让 OP 给出一个如何使用的想法......根据完整要求进行了修改。跨度>
  • 谢谢,但我在哪里使用 for 循环中的“i”int?您只是使用“x” int。
  • 你是用 i 来做索引的吧?然后使用您将x 插入集合的位置... @Vettel.Sebastian
  • 有什么方法可以像我的代码中那样使用 int 块吗?
  • @Vettel.Sebastian.:您可以添加该声明...您想要清楚说明什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-25
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
  • 2013-12-24
相关资源
最近更新 更多