Алгоритм STL, аналогичный преобразованию, который позволяет получить доступ к ранее преобразованному элементу, аналогичному накоплению. - PullRequest
2 голосов
/ 11 мая 2019

Существует ли алгоритм STL, который позволяет мне применять функцию к каждому элементу в диапазоне, преобразовывая элемент, с предварительно преобразованным элементом в качестве входа?

Я думаю, что-то вроде этого (очевидно, неработа, так как второй итератор будет недействительным):

struct Input
{
    int width;
};

struct Output
{
    int x;
    int width;
};

Output transform_input(const Input &input, const Output &previous)
{
    return { previous.x + previous.width, input.width };
}

int main()
{
    std::vector<Input> input = { { 30 }, { 60 }, { 10 } };
    std::vector<Output> output;

    std::transform(std::begin(input)
        , std::end(input)
        , std::prev(std::begin(output))
        , std::back_inserter(output)
        , transform_input
        );
}

Ожидаемый результат здесь для output, который содержит 3 элемента типа Output со следующим содержанием:

  • Элемент 0, где x == 0 и width == 30
  • Элемент 1, где x == 30 и width == 60
  • Элемент 2, где x == 90 и width == 10

Чтобы это сработало, я полагаю, что алгоритм должен был бы позволить мне указать начальное число, или, альтернативно, создать конструкцию по умолчанию для меня.

Я уже рассмотрел transform и adjacent_difference.

Использование transform может работать с каким-то пользовательским итератором, или, может быть, есть один встроенный в STL, который я мог бы использовать?

Хотя adjacent_difference показалось многообещающим, он только даст мне доступк предыдущему элементу для итерации вводаили.

Если нет встроенного алгоритма, удовлетворяющего моим требованиям, то как называется такой алгоритм?

1 Ответ

2 голосов
/ 11 мая 2019

Вы можете использовать std::transform и передать лямбду, которая захватывает ваш выходной контейнер.

std::transform(std::begin(input)
    , std::end(input)
    , std::back_inserter(output)
    , [&](auto& input) {
        if (output.empty()) {
            return transform_input(input, {});
        } else {
            return transform_input(input, output.back());
        }
    );
...