【问题标题】:How to get column-view and row-view from std::vector using range-v3 library?如何使用 range-v3 库从 std::vector 获取列视图和行视图?
【发布时间】:2018-12-20 15:33:21
【问题描述】:

将 7x5 矩阵展平为 std::vector,我想使用 Eric Niebler 的 range-v3 库查看列和行。到目前为止,我设法(改进空间)获得了单行、单列和连接行的视图。

见:https://wandbox.org/permlink/8o4RgSucF3zSNuPN

std::vector<int> numbers = {
    00, 01, 02, 03, 04,
    10, 11, 12, 13, 14,
    20, 21, 22, 23, 24,
    30, 31, 32, 33, 34,
    40, 41, 42, 43, 44,
    50, 51, 52, 53, 54,
    60, 61, 62, 63, 64,
};
const size_t n = 5;//number of columns

//Row_3 = {30, 31, 32, 33, 34}
auto Row_3 = numbers | GetRow(3, n);
std::cout << Row_3 << std::endl;

//Col_2 = {02, 12, 22, 32, 42, 52, 62}
auto Col_2 = numbers | GetColumn(2, n);
std::cout << Col_2 << std::endl;

//Row_2_3_4 =  {{20, 21, 22, 23, 24},
//              {30, 31, 32, 33, 34},
//              {40, 41, 42, 43, 44}}
auto Rows_2_3_4 = numbers | GetConnectedRows(2, 4, n);
std::cout << Rows_2_3_4 << std::endl;

但是我怎样才能快速了解:

  1. 行列表:

    auto a = numbers | GetRows({2,3,5}, n);

  2. 连接的列:

    auto b = numbers | GetCols(2, 4, n);

  3. 列列表:

    auto c = numbers | GetCols({1,2,4}, n);

  4. 行列表(“未排序”):

    auto d = numbers | GetRows({5,2,3}, n);

  5. 列列表(“未排序”):

    auto e = numbers | GetCols({4,1,2}, n);

?

【问题讨论】:

    标签: c++ range-v3


    【解决方案1】:

    您可以将索引通过管道传输到适当的ranges::view::transform

    在课堂上总结:

    class Matrix
    {
        std::vector<int> data;
        size_t col_count;
    
        auto to_row(){ return [this](size_t i){ return data | ranges::view::drop(i * col_count) | ranges::view::take(col_count); }; };
        auto to_col(){ return [this](size_t i){ return data | ranges::view::drop(i) | ranges::view::stride(col_count); }; };
    
    public:
        auto get_rows(size_t start, size_t end)
        { return ranges::view::ints(start, end) | ranges::view::transform(to_row()); }
    
        auto get_rows(std::initialiser_list<size_t> indexes)
        { return indexes | ranges::view::transform(to_row()); }
    
        auto get_cols(size_t start, size_t end)
        { return ranges::view::ints(start, end) | ranges::view::transform(to_col()); }
    
        auto get_cols(std::initialiser_list<size_t> indexes)
        { return indexes | ranges::view::transform(to_col()); }
    };
    

    或作为可管道视图

    auto GetColumns(std::initialiser_list<size_t> indexes, size_t n)
    {
        return ranges::make_pipeable([=](auto &&rng) {
            auto to_col = [&rng, n](size_t i){ return rng | GetCol(i, n); };
            return indexes | ranges::view::transform(to_col);
        });
    }
    
    auto GetRows(std::initialiser_list<size_t> indexes, size_t n)
    {
        return ranges::make_pipeable([=](auto &&rng) {
            auto to_row = [&rng, n](size_t i){ return rng | GetRow(i, n); };
            return indexes | ranges::view::transform(to_col);
        });
    }
    

    【讨论】:

    • 我在 wandbox 示例中包含了您的解决方案:link 但我还有两个问题: 1. 是否有可能使您的课程解决方案可管道化?我想编写如下代码:auto submatrix = numbers |获取列(2,n)| GetConnectedRows(2, 4, 1);//submatrix = {22,32,42} 2. 连接行的性能如何?你的解决方案有点像一个循环,对吧?一次又一次地删除第一个 i 元素...无论如何,非常感谢您的帮助
    • @Porsche9II 是的,我只需要了解管道视图所涉及的管道。至于性能,因为vector 是一个随机访问容器,而且所有的视图都是惰性的,所以它的性能非常好。没有任何值的复制发生
    • @Porsche9II 或调用GetColumnsGetRows 中的任何迭代
    猜你喜欢
    • 2021-07-13
    • 2023-03-14
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多