Есть ли алгоритм STL, который находит последним, но также работает с указателями? - PullRequest
0 голосов
/ 29 мая 2020

У меня есть код, в котором я не могу переключиться на итераторы. Тем не менее, я хотел бы использовать STL, если возможно, чтобы найти последний элемент (или первый, если вы считаете, что мы выполняем итерацию с конца). Возможно ли это?

std :: find_end помимо того, что алгоритм с наихудшим именем когда-либо кажется довольно уродливым в использовании (мне понадобится поддельная последовательность из 1 элемента и двоичный предикат, который игнорирует значения 1 элемента при сравнении).

То, что у меня есть сейчас, довольно уродливо (тем более, что обратное преобразование bool * не является bool *, поэтому мне приходится делать уродливые вещи, чтобы получить std :: distance.

#include <algorithm>
#include <iostream>

int main()
{ 
    {
    bool arr[6] = {true,false,true,true,true,false};
    auto e = std::make_reverse_iterator(&arr[0]);
    auto b = std::make_reverse_iterator(&arr[6]);
    auto it = std::find(b,e, false);
    if (it!=e){
        std::cout << "index of last false is " << &(*it) - &arr[0] << std::endl;
    }
    }
    // repeat test to make sure result is not an accident
    {
    bool arr[6] = {true,false,true,true,false,true};
    auto e = std::make_reverse_iterator(&arr[0]);
    auto b = std::make_reverse_iterator(&arr[6]);
    auto it = std::find(b,e, false);
    if (it!=e){
        std::cout << "index of last false is " << &(*it) - &arr[0] << std::endl;
    }
    }
}

Ответы [ 2 ]

4 голосов
/ 29 мая 2020

Правильный способ найти индекс последнего элемента в контейнере (включая c массивы) - использовать std::find с reverse_iterator s (для двунаправленных контейнеров), как вы пробовали, но с меньшим количеством UB (&arr[6] - уб).

using std::begin;
using std::rbegin;
using std::rend;

bool arr[6] = {...};
auto it = std::find(rbegin(arr), rend(arr), false);
if (it != rend(arr)) {
    auto idx = std::distance(begin(arr), it.base()) - 1;
    std::cout << "idx is " << idx << std::endl;
}
1 голос
/ 29 мая 2020

Я не уверен, правильно ли я понял, что вам нужно, но этот код, похоже, работает нормально:

int arr[6] = { 1, 2, 3, 4, 5 };
int pattern[1] = { 4 };
auto it = std::find_end(arr, arr + 5, pattern, pattern + 1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...