【问题标题】:STL or ranges algorithm to efficiently find n consecutive elements that satisfy predicateSTL 或范围算法可有效地找到满足谓词的 n 个连续元素
【发布时间】:2020-01-29 02:10:53
【问题描述】:

我有以下功能(玩具示例,但适合演示):

  // finds the iterator pointing to the start of n consectuve 47s or return values.end() if not found
  auto find_n_47s(const int n, const std::vector<int>& values){
    std::vector<bool> predicate_result;
    predicate_result.reserve(values.size());
    std::transform(values.begin(), values.end(), std::back_inserter(predicate_result), []
                   (const auto& val){return val==47; });
    std::vector<bool> search_pattern(n, true);
    auto it= std::search(predicate_result.begin(), predicate_result.end(), 
                       search_pattern.begin(), search_pattern.end());
    return values.begin() + std::distance(predicate_result.begin(), it);  
}

我正在寻找一种更好、更有效的方法来完成同样的事情。

我的问题:

  1. 我不能使用手动迭代 + std::all_of(从当前元素到 前面有 n 个元素)因为它太慢了(理论上对于每个元素 我最多做 n 个谓词应用程序)。

  2. 我的解决方案分配内存并为每个 尽管我们可能会在前 1% 中找到结果 元素。

完整代码在这里:https://wandbox.org/permlink/rBVFS64IcOI6gKe6

【问题讨论】:

  • "理论上,对于我所做的每个元素,最多 n 个谓词应用程序" 你怎么可能知道什么时候得到结果?就谓词的调用次数而言,您想要的必须是 O(n)。这与要求小于 O(n) 的排序算法没有什么不同;这在逻辑上是不可能的,因为您必须至少进行 n 次比较才能知道序列已排序。
  • @NicolBolas n 不是向量的大小,而是子序列的长度
  • @CruzJean - 它不适用于自定义一元谓词
  • @NoSenseEtAl 在这种情况下,二元谓词是一元谓词的超集:只需将一些值传递给它以搜索并让您的二元谓词将该类型作为第二个参数,但仅基于第一个参数参数

标签: c++ stl c++20 range-v3


【解决方案1】:

正如 Cruz Jean 指出的,您可以使用 search_n:

https://wandbox.org/permlink/ENgEi5ZVPDx1D1GQ

search_n的GCC实现

https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_algo.h

不检查每个元素:

|---------|---------|---------|----------------|
|  Find first occurence of n=7 consecutive 47  |
|---------|---------|---------|----------------|
|  vector |  step#  |  count  |                |
|---------|---------|---------|----------------|
|  47     |         |         |                |
|  47     |         |         |                |
|  47     |         |         |                |
|  0      |  4      |  3      |                |
|  47     |  3      |  3      |                |
|  47     |  2      |  2      |                |
|  47     |  1      |  1      |  start         |
|  47     |         |         |                |
|  47     |         |         |                |
|  0      |  5      |  0      |                |
|  47     |         |         |                |
|  0      |         |         |                |
|  0      |         |         |                |
|  47     |         |         |                |
|  0      |         |         |                |
|  47     |         |         |                |
|  0      |  6      |  0      |                |
|  0      |         |         |                |
|  0      |         |         |                |
|  0      |         |         |                |
|  0      |         |         |                |
|  47     |         |         |                |
|  0      |         |         |                |
|  0      |  7      |  0      |                |
|  47     |         |         |                |
|  47     |         |         |                |
|  47     |         |         |                |
|  47     |         |         |                |
|  0      |         |         |                |
|  0      |  9      |  1      |                |
|  47     |  8      |  1      |                |
|  47     |  15     |  7      |  success       |
|  47     |  14     |  6      |                |
|  47     |  13     |  5      |                |
|  47     |  12     |  4      |                |
|  47     |  11     |  3      |                |
|  47     |  10     |  2      |                |
|  47     |         |         |                |
|  0      |         |         |                |
|  0      |         |         |                |
|  47     |         |         |                |
|  0      |         |         |                |
|  …      |         |         |                |
|---------|---------|---------|----------------|

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 2018-07-21
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多