我有一个容器,我想选择一个随机满足谓词的迭代器。如果它有助于具体化,那么容器就是一张地图。
天真地,我会说:
std::count_if
获取范围内的元素数量。
选择随机数btwn 0
和num_elements-1
。
创建一个lambda来创建一个有状态谓词,该谓词最多可以计算随机数,然后只返回true。
std::find_if
与lambda。
这会有效吗?还有更好的方法吗?或者,我可以使用count而不是count_if,并在谓词失败时重新生成数字。如果我认为谓词大部分都是正确的,那么可能会有用,但对我的目的来说不会很好。
答案 0 :(得分:1)
您可以通过在单独的容器中存储谓词为true的所有迭代器来交换内存以获得性能,然后使用随机数从中选择迭代器。这样你只需要遍历序列一次(注意,你仍然需要一个前向迭代器,因为一旦你移动到下一个元素,存储的输入迭代器就会失效)。例如:
template<typename ForwardIterator, typename Predicate>
ForwardIterator random_iterator(ForwardIterator first,
ForwardIterator last,
Predicate pred)
{
// store iterators to elements where the predicate is true
std::deque<ForwardIterator> store;
for (; first != last; ++first)
if pred(*first)
store.push_back(first);
// if no element satisfies the predicate, return last
if (store.size() == 0)
return last;
// get a random number in range [0, store.size())
int rand = get_random_number(store.size());
// return the corresponding iterator
return store[rand];
}