【问题标题】:Non-repeating random numbers in vector C++向量 C++ 中的非重复随机数
【发布时间】:2017-11-10 22:56:37
【问题描述】:

我正在尝试将随机数存储在向量中,但我希望每个数字都是唯一的。我可以在不使用 unique() 或 random_shuffle() 的情况下使用 for 循环吗?

#include <iostream>
#include <vector>
#include <ctime>

using namespace std;

int main()
{

    srand(time(NULL));

    vector<int> v;

    for (unsigned int i = 0; i < 30; i++) {

          v.push_back(rand() % 30);
    }

    for (unsigned int j = 0; j < 30; j++) {

        cout << v[j] << endl;
    }

    return 0;
}

【问题讨论】:

  • 你只是想随机化顺序吗?
  • 你为什么坚持一个困难而低效的解决方案?生成一个有序的向量,然后打乱它。
  • 如果你不想使用标准库的随机洗牌,那就自己写吧。 Fisher-Yates shuffle 用 rand() 本身很容易实现。
  • 不只是“随机数”,您必须指定分布。如果您不关心分布,请使用 1,2,3,...,30。

标签: c++ vector random numbers


【解决方案1】:

经典的Fisher–Yates shuffle也可以用来直接生成一个shuffled向量,一次pass

vector<unsigned> v;

for (unsigned i = 0; i < 30; ++i)
{
  unsigned j = rand() % (i + 1);
  if (j < i)
  {
    v.push_back(v[j]);
    v[j] = i;
  }
  else
    v.push_back(i);
}

【讨论】:

    【解决方案2】:

    您可能应该生成向量并对其进行随机播放:

    #include <iostream>
    #include <ctime>
    #include <utility>
    
    int main()
    {
    
        std::srand(static_cast<unsigned int>(std::time(NULL)));
        size_t const n = 30;
        std::vector<int> v(n);
    
        //make vector
        for (size_t i = 0; i < n; ++i)
            v[i] = static_cast<int>(i);
    
        //shuffle
        for (size_t i = n - 1; i > 0; --i)
            std::swap(v[i], v[static_cast<size_t>(rand()) % (i + 1)]);
    
        //print
        for (size_t i = 0; i < n; ++i) 
            std::cout << (i > 0 ? "," : "") << v[i];
    
        return 0;
    }
    

    打印,例如:

    27,24,2,23,13,6,9,14,11,5,15,18,16,29,22,12,26,20,10,8,28,25,7,4,1,17,0,3,19,21
    

    【讨论】:

    • 您自制的 ad-hoc shuffle 会产生非均匀分布(在此类问题中通常暗示/需要)。最好使用std::shuffle 或至少实现Fisher-Yates shuffle(又名“Knuth shuffle”),这是一种极其简单的算法。
    • 您似乎打算从 Wikipedia 页面实现“前向”Fisher-Yates 洗牌。但为此重要的是要记住,交换的随机索引应该在[i, n) 范围内生成。您在[0, n) 范围内生成索引。这不是Fisher-Yates,这仍然是不均匀的。
    猜你喜欢
    • 1970-01-01
    • 2013-12-24
    • 2010-12-09
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    相关资源
    最近更新 更多