Как склеить вектор векторов в один вектор с помощью transform_reduce?

Рейтинг: 1Ответов: 2Опубликовано: 24.03.2023
#include <iostream>
#include <iterator>
#include <vector>
#include <numeric>
#include <string>


using namespace std;

int main() {

    vector<vector<string>> vv = {
            {"aaaaaa"s, "bbbbbb"s, "cccccc"s},
            {"dddddd"s, "eeeeee"s, "ffffff"s, "jjjjjj"s}
    };

    vector<string> v;

    // ...

    copy(v.begin(), v.end(), ostream_iterator<string>(cout, " "));
    return 0;
}

// Вывод:
// aaaaaa bbbbbb cccccc dddddd eeeeee ffffff jjjjjj

Нужно с помощью transform_reduce (или любого другого параллельного алгоритма, относящегося к концепции MapReduce), получить в стадии reduce один вектор строк из вектора векторов строк. Контейнер может быть любым, не обязательно вектор.

Размеры вложенных векторов могут отличаться.

Ответы

▲ 1Принят
    // операция склеивания двух списков в один
    auto list_splice=[]( list<string> lhs, list<string> rhs ) -> list<string>
    {
        lhs.splice( lhs.end(), rhs );
        return lhs;
    };

    list<string> l = std::reduce( execution::par_unseq, ll.begin(), ll.end(), list<string>{}, list_splice);
▲ 0
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <list>
#include <execution>

using namespace std;

int main() {

    list<list<string>> ll = {
            {"aaaaaa"s, "bbbbbb"s, "cccccc"s},
            {"dddddd"s, "eeeeee"s, "ffffff"s, "ggggggg"s}
    };

    list<string> l;

    transform_reduce(execution::par, ll.begin(), ll.end(), ""s, std::plus<string>(), [&l](list<string> in) {
        l.insert(l.end(), in.begin(), in.end());
        return ""s;
    });

    copy(l.begin(), l.end(), ostream_iterator<string>(cout, " "));
    return 0;
}
// Вывод:
// aaaaaa bbbbbb cccccc dddddd eeeeee ffffff ggggggg

Вот такой вариант работает, но хотелось бы более элегантное решение, потому что тут костыль - пустая строка ""s складывается.

И еще вопрос, метод insert в лямбде не повлияет на распараллеливание алгоритма?