Алгоритм STL или диапазонов для эффективного поиска n последовательных элементов, удовлетворяющих предикату - PullRequest
1 голос
/ 29 сентября 2019

У меня есть следующая функция (пример с игрушкой, но она подходит для демонстрации):

  // 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

1 Ответ

4 голосов
/ 29 сентября 2019

Как заметил Круз Джин, вы можете использовать search_n:

https://wandbox.org/permlink/ENgEi5ZVPDx1D1GQ

GCC-реализация search_n

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      |         |         |                |
|  …      |         |         |                |
|---------|---------|---------|----------------|
...