Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在这里: 序数向量填充稀疏_C++_Vector_Random - Fatal编程技术网

C++ 在这里: 序数向量填充稀疏

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的解决方案将

为了解决问题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);
12的解决方案将更加复杂,因为我建议将
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
然后迭代直到找到一个。@iBug
std::shuffle
不会帮助程序压缩它。@JakeFreeman创建索引数组然后洗牌索引也可以。随机方法很好,特别是如果你可以缓存你已经尝试过的索引,这样你就不会再尝试它们了。
std::shuffle
然后迭代直到找到一个。@iBug
std::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);