C++ 在这里: 序数向量填充稀疏
为了解决问题1我建议使用C++ 在这里: 序数向量填充稀疏,c++,vector,random,C++,Vector,Random,为了解决问题1我建议使用map foo这将允许您使用非线性索引,但它不需要中间空向量的填充。这里选择一个随机填充的元素只需要将迭代器向前移动,以指向适当的元素。例如,result将是foo中随机键值对的常量迭代器: const auto idx = foo.empty() ? 0U : std::mt19937{std::random_device{}()}() % size(foo); const auto result = next(cbegin(foo), idx); 1和2的解决方案将
map foo
这将允许您使用非线性索引,但它不需要中间空向量的填充。这里选择一个随机填充的元素只需要将迭代器向前移动,以指向适当的元素。例如,result
将是foo
中随机键值对的常量迭代器:
const auto idx = foo.empty() ? 0U : std::mt19937{std::random_device{}()}() % size(foo);
const auto result = next(cbegin(foo), idx);
1和2的解决方案将更加复杂,因为我建议将vector
s一起删除,以支持multimap foo
这包含了map
解决方案的所有好处,但折衷是必须使用上界
迭代键。此外,由于multimap
不存储密钥计数,因此需要将size\u t keyCount
与multimap
一起维护。或者假设它是一个临时初始化为0U
的文件,在需要它时可能会浪费时间:for(auto-it=cbegin(foo);it!=cend(foo);it=foo.upper_-bound(it->first))++keyCount
使用keyCount
我们可以再次找到result
,它将是与随机键匹配的第一个元素的常量迭代器:
int idx = keyCount == 0U ? 0 : std::mt19937{std::random_device{}()}() % keyCount;
auto result = cbegin(foo);
while(idx-- > 0) result = foo.upper_bound(result->first);
std::shuffle
然后迭代直到找到一个。@iBugstd::shuffle
不会帮助程序压缩它。@JakeFreeman创建索引数组然后洗牌索引也可以。随机方法很好,特别是如果你可以缓存你已经尝试过的索引,这样你就不会再尝试它们了。std::shuffle
然后迭代直到找到一个。@iBugstd::shuffle
不会帮助程序压缩它。@JakeFreeman创建一个索引数组,然后对索引进行shuffle也可以。随机方法很好,特别是如果你可以缓存你已经尝试过的索引,这样你就不会再尝试它们了。这种想法并不那么有效,因为你要存储2倍的内存,并且需要时间来不断确保它们是相同的。使用哈希表来维护索引需要不断的时间。关于记忆,是的,它需要记忆。但是内存是免费的:d这个想法没有那么有效,因为您存储了2倍的内存,并且需要时间来不断确保它们是相同的。使用哈希表来维护它们需要不断的时间。关于记忆,是的,它需要记忆。但是内存是免费的:D
#include <algorithm>
#include <functional>
#include <iterator>
#include <random>
#include <vector>
#include <iostream>
int main() {
using int_vec_t = std::vector<int>;
std::vector<int_vec_t> v = {
{0, 1, 2}, {}, {}, {3, 4, 5},
{}, {6, 7, 8}, {}, {}, {9}, {10, 11}
};
// You can't put reference direcly, so use reference_wrapper instead
std::vector<std::reference_wrapper<int_vec_t> > nonempty;
nonempty.reserve(v.size());
// "copy" non empty vectors. (Doesn't do copy, actually)
std::copy_if(v.begin(), v.end(), std::back_inserter(nonempty), [](const int_vec_t& v) { return !v.empty();});
if (nonempty.empty())
return 0;
// pick an element
static std::random_device rd;
static std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, nonempty.size() - 1);
const int_vec_t& result = nonempty[dis(gen)];
// dump result
std::copy(result.begin(), result.end(), std::ostream_iterator<int>(std::cout, ", "));
return 0;
}
const auto idx = foo.empty() ? 0U : std::mt19937{std::random_device{}()}() % size(foo);
const auto result = next(cbegin(foo), idx);
int idx = keyCount == 0U ? 0 : std::mt19937{std::random_device{}()}() % keyCount;
auto result = cbegin(foo);
while(idx-- > 0) result = foo.upper_bound(result->first);