C++能否实现类似现代Fortran的数组切片操作?需引入哪些头文件?
C++中实现类似Fortran的数组切片操作
在C++里,要实现和Fortran类似的低开销数组切片、列提取操作,分两种场景:用标准库原生工具,或者借助第三方线性代数库。
一、使用C标准库(C20及以上)
需要引入的头文件:<array>(固定大小数组)、<vector>(动态数组)、<span>(零开销视图)、<algorithm>(复制操作)、<ranges>(C++20范围视图)。
1. 提取二维数组的某一列到一维数组
假设A是9×9的固定大小数组,要提取第4列(注意C++是0起始索引,对应Fortran的第4列是索引3):
#include <array> #include <algorithm> std::array<std::array<int, 9>, 9> A; std::array<int, 9> V; // 复制A的第4列到V std::transform(A.begin(), A.end(), V.begin(), [](const auto& row) { return row[3]; });
如果想要零开销的视图(不复制数据),可以用C++20的范围视图:
#include <array> #include <ranges> auto V_view = A | std::views::transform([](const auto& row) { return row[3]; });
2. 切片一维数组的子区间
对一维数组V,提取第4到第8个元素(对应C++索引4到7,共4个元素),用std::span实现零开销视图:
#include <array> #include <span> std::array<int, 9> V; auto W = std::span(V).subspan(4, 4); // 起始索引4,长度4
3. 提取二维数组的子数组
提取A的第3-4行、第5-9列(对应C++索引2-3行、4-8列),如果要零开销视图,需要结合span和范围视图:
#include <array> #include <span> #include <ranges> // 先取2-3行的视图,再对每行取4-8列的视图 auto S_view = A | std::views::drop(2) | std::views::take(2) | std::views::transform([](const auto& row) { return std::span(row).subspan(4, 5); });
如果需要复制出实际的子数组,需要手动遍历或用算法填充。
二、使用第三方线性代数库(如Eigen)
如果追求和Fortran几乎完全一致的简洁语法,且零开销操作,推荐用Eigen库。需要引入的头文件:<Eigen/Dense>。
对应Fortran操作的Eigen实现
#include <Eigen/Dense> // 定义9×9矩阵 Eigen::Matrix<int, 9, 9> A; // 提取第4列到一维数组V(Eigen中col()是列索引,0起始) Eigen::Vector<int, 9> V = A.col(3); // 切片V的第4-8个元素(segment(起始索引, 长度)) auto W = V.segment(4, 4); // 提取2×5子数组:起始行2,起始列4,行数2,列数5 auto S = A.block(2, 4, 2, 5);
Eigen的这些操作默认都是零开销的视图(仅访问原数据,不复制),和Fortran的操作特性完全一致,语法也更接近。
内容的提问来源于stack exchange,提问作者Mephisto
相关产品推荐
相关产品推荐

