具有随机数的唯一向量
unique vector with random numbers
我的程序是编写一个 c++ 程序初始化大小为 SIZE 的整数向量 v,每个整数在 [0,2*SIZE] 范围内,我如何确保向量中的所有数字都是唯一的我如何编辑我的初始化向量以使其正常工作,我的逻辑中有缺陷。不能使用随机播放。
#include <iostream>
#include <ctime>
#include <vector>
#include <iomanip>
#include<algorithm>
const int SIZE =10;
unsigned int seed = (unsigned)time(0);
using namespace std;
double random (unsigned int &seed);
void print_vector (vector<int> :: iterator b,
vector<int> :: iterator e );
void initialize_vector(vector<int> &v);
vector<int>v;
int main()
{
cout << endl;
initialize_vector(v);
cout << "Vector : " << endl;
print_vector(v.begin(), v.end());
return 0;
}
double random(unsigned int &seed)
{
const int MODULUS = 15749;
const int MULTIPLIER = 69069;
const int INCREMENT = 1;
seed = ((MULTIPLIER*seed)+INCREMENT)%MODULUS;
return double (seed)/MODULUS;
}
void initialize_vector(vector<int> &v)
{
vector<int> used;
int count_unused, k;
for (int i=0; i<2*SIZE; i++)
{
used.push_back(0);
}
for (int i=0; i<SIZE; i++)
{
int j= (random(seed)*(2*SIZE+1-i)) + 1;
count_unused = 0;
k = 0;
while (count_unused != j)
{
if (used[k] == 0)
count_unused++;
k++;
}
used[k] = 1;
v.push_back(j);
}
}
void print_vector (vector<int> :: iterator b,
vector<int> :: iterator e )
{
vector<int> :: iterator p =b;
while(p<e)
cout << setw(3) << (*p++);
cout << endl;
}
std::iota
和 std::random_shuffle
1 就可以解决问题:
constexpr int SIZE = 10;
std::vector<int> values(2*SIZE+1);
std::iota(begin(values), end(values), 0);
std::random_shuffle(begin(values), end(values));
values.resize(SIZE);
完整演示:http://coliru.stacked-crooked.com/a/0caca71a15fbd698
它是如何工作的?
首先,创建一个2*SIZE+1
向量...
std::vector<int> values(2*SIZE+1);
。并填充从 0
到 2*SIZE
的连续整数。
std::iota(begin(values), end(values), 0);
我们洗牌这些价值观...
std::random_shuffle(begin(values), end(values));
。并删除第二个无用的一半。
values.resize(SIZE);
瞧。
<小时 />1( 注意:这是一个 C++11/14 解决方案,因为自 C++14 起std::random_shuffle
已被弃用,并在 c++17 中删除。
好的,这是没有任何存储的解决方案,并基于水库采样进行检查。我们模拟值从 0 到 2*SIZE(包括 0 到 2*SIZE(的流,并以相等的概率填充水库。无需预填充然后擦除数据,一次采样。不洗牌!代码,视觉C++ 2019
#include <iostream>
#include <vector>
#include <random>
constexpr int SIZE = 10;
constexpr int EOS = -1; // end-of-stream marker
static int s = 0;
void init_stream() {
s = 0;
}
int next_stream() {
if (s > 2 * SIZE)
return EOS;
return s++;
}
std::mt19937_64 rng{ 1792837ULL };
int random(int lo, int hi) {
std::uniform_int_distribution<int> ud{ lo, hi };
return ud(rng);
}
std::vector<int> reservoir(int size) {
std::vector<int> r(size, 0);
auto v = next_stream(); // value from stream
for (int k = 0; v != EOS; ++k, v = next_stream()) {
if (k < r.size()) { // fill reservoir
r[k] = v;
}
else { // replace elements with gradually decreasing probability
unsigned int idx = random(0, k);
if (idx < r.size()) {
r[idx] = v;
}
}
}
return r;
}
int main() {
std::vector<int> h(2*SIZE+1, 0);
for (int k = 0; k != 100000; ++k) {
init_stream();
std::vector<int> r{ reservoir(SIZE) };
for (auto v : r) {
h[v] += 1;
}
}
for (auto v : h) {
std::cout << v << 'n';
}
return 0;
}
打印的直方图显示相当均匀的分布。
正如 sv90 在没有shuffle
的情况下提到的,或者对于非常大的SIZE
,您可能更喜欢unordered_set
来确保唯一的数字。使用uniform_int_distribution
初始化此unordered_set
,然后使用此unordered_set
初始化vector
。像这样:
unordered_set<int> initialize_vector;
mt19937 g{ random_device{}() };
const uniform_int_distribution<int> random{ 0, SIZE };
while(size(initialize_vector) < SIZE) {
initialize_vector.insert(random(g));
}
const vector<int> v{ cbegin(initialize_vector), cend(initialize_vector) };
现场示例
相关文章:
- 计算排序向量的向量中唯一值的计数
- 如何更改唯一指针向量的可见性
- 使用 RTTI 克隆唯一指针的向量
- C++模板功能检查唯一向量
- C++唯一指针的向量
- 从数组中删除非唯一值、保持顺序和不使用向量的最佳方法?
- tbb:current_unordered_map()-向量中每个唯一元素的ID
- 初始化 C++14 中唯一指针向量的正确方法
- 对唯一 ptr 无效读取的引用向量
- 在创建对象向量时,不为每个对象唯一调用默认对象构造函数
- 如何打印出唯一指针对象向量中的值(基于范围的循环)?C++
- 如何从向量正确返回唯一的_ptr
- C 移动语义:将唯一_ptr引用的矩阵附加到向量
- 在迭代过程中删除向量的唯一元素?
- 具有随机数的唯一向量
- 检查每行/列中的值在向量中是否唯一
- 如何在满足谓词的向量中获得唯一PTR的子集
- 将唯一的_ptr插入向量为一对
- 采用向量中包含的唯一指针的 Lambda 表达式
- 找到唯一向量的索引和逆映射