从满足谓词的迭代器中均匀随机地从容器中获取迭代器

时间:2017-01-28 05:39:07

标签: c++ c++11 random iterator

我有一个容器,我想选择一个随机满足谓词的迭代器。如果它有助于具体化,那么容器就是一张地图。

天真地,我会说:

std::count_if获取范围内的元素数量。

选择随机数btwn 0num_elements-1

创建一个lambda来创建一个有状态谓词,该谓词最多可以计算随机数,然后只返回true。

std::find_if与lambda。

这会有效吗?还有更好的方法吗?或者,我可以使用count而不是count_if,并在谓词失败时重新生成数字。如果我认为谓词大部分都是正确的,那么可能会有用,但对我的目的来说不会很好。

1 个答案:

答案 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];
}
相关问题