如何在C++中选择多维数组中的一个范围
how to select a range in multidimensional array in C++?
假设我有:
int array[9][9]= {
{1 , 2 , 3 , 4, 5, 6, 7, 8, 9},
{10, 11, 12, 13, 14, 15, 16, 17, 18},
{19, 20, 21, 22, 23, 24, 25, 26, 27},
{28, 29, 30, 31, 32, 33, 34, 35, 36},
{37, 38, 39, 40, 41, 42, 43, 44, 45},
{46, 47, 48, 49, 50, 51, 52, 53, 54},
{55, 56, 57, 58, 59, 60, 61, 62, 63},
{64, 65, 66, 67, 68, 69, 70, 71, 72},
{73, 74, 75, 76, 77, 78, 79, 80, 81}
};
我怎么能只对第一行(值1到9)或第一列(像值1到73)应用一些函数呢。比方说,我想说索引0到9都应该具有值0。
可以将这个范围保存在变量中吗?
试着这样做:
for (int i = 0; i<10; i++)
array[0][i] = 0;
C.中没有真正的多维数组
在一个真正的多维数组中,所有维度都是平等的。无论你能对行做什么,你也能对列做什么。
C++的情况并非如此。阵列的第三行只是
array[3]
它在各个方面都是一个独立的阵列。与任何其他范围一样,行的范围可以表示为(开始、结束)对,例如make_pair(array[3], array[7])
。
没有什么可以用列来完成的。与第三行不同,第三列不是数组,它只是一个不在任何标准数据结构保护伞下的元素的虚拟集合。
最接近多维数组切片的是自定义迭代器,因此++i
移动到右边的下一个元素或下面的下一元素。当你在做的时候,考虑从C风格的数组转移到STL风格的容器。
要隔离数组的行,可以引用数组的一行:
int (&row)[9] = array[2];
例如,上面的行引用了数组的第三行。
实时演示
对于列,则更为复杂。
或者,您可以执行以下构造,将引用包装器的向量返回到2D数组的列或行。
// if flg == true you get row at idx else if flg == false you get column at idx
template<typename T, int N, int M>
std::vector<std::reference_wrapper<T>>
getRange(T (&arr)[N][M], std::size_t const idx, bool const flg = true) {
if(flg) {
return typename std::vector<std::reference_wrapper<T>>(std::begin(arr[idx]), std::end(arr[idx]));
} else {
typename std::vector<std::reference_wrapper<T>> out;
out.reserve(N);
for(int i(0); i < N; ++i) out.push_back(arr[i][idx]);
return out;
}
}
实时演示
对于行,这很容易,因为您可以像一样传递它们
void foo(int * row, int cols) {
for (int col = 0; col < cols; ++col) {
int * x = row + col;
}
}
...
foo(array[3], 9);
...
对于列来说,这更困难,但您可以将每一列视为数组中具有特定偏移量的列:
void boo(int * col, int rows, int cols) {
for (int row = 0; row < rows; ++row) {
int * x = col + row * cols;
}
}
....
// process fourth column:
boo(array[0]+4, 9, 9);
当然,使用sizeof而不是"9",使用C++矢量/数组而不是C样式的int[][]将使生活更加轻松,代码也更加可读和可支持。
另一种方法是使用boost::矩阵,例如:
using namespace boost::numeric::ublas;
matrix<double> m(9, 9);
matrix_row<matrix <double> > row(m, 5);
matrix_column<matrix <double> > col(m, 4);
您可以通过在函数中指定索引(起始和结束范围)并说明它应该应用于行还是列来实现。由于您使用的是纯C风格的数组,因此处理指针更为棘手。我建议您使用vector
s和pair
s(用于范围)。
C型阵列的一个例子
void some_function(int array[][9], bool row_or_column, size_t major, size_t start, size_t end){
if (row_or_column = true) {
for (int i = start; i < end; i++) {
cout << array[major][i]; //perform your operation on row
}
}
else {
for (int i = start; i < end; i++) {
cout << array[i][major]; //perform your operation on column
}
}
}
将row_or_column
设置为行的true
或列的false
,major
应指定列号或行号以及start
和end
中的范围。注:end
为专属
用于处理范围为start = 0
和end = 5
的第二行,即10到14some_function(array, true, 1, 0, 5)
用于处理范围为start = 0
和end = 5
的第二列,即2到38some_function(array, false, 1, 0, 5)
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何设置一个范围来提取我想要获得的信息
- 不计算一个范围内的完美数
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- 我有一个数组,我想输入一个范围,然后找到范围内所有偶数的总和?
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 在 C++20 中将多个范围适配器连接到一个范围中
- 转到基于范围的 for 循环中的下一个迭代器
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 有没有办法在另一个函数中加入线程?(即超出其自身范围)
- 如何将一个范围替换为矢量中的另一个范围?
- 包含来自另一个文件的函数会导致范围错误(openFoam)
- 定义一个 void f(void) 函数,但使用来自同一范围的变量?
- 越界成员函数定义是否需要一个完全限定的类名,直到全局范围
- 如何使用基于范围的for循环迭代Rapidjson文档(它本身就是一个JSON数组)
- 将整数范围映射到另一个范围
- 是否存在一个范围::视图::group_by对应项,它将所有元素都考虑在内,而不是只考虑连续的元素
- 检查IP是否在其他IP网络范围内,并查找下一个可用IP
- 为什么基于范围的 for 循环中的结构化绑定只是一个副本而不是引用?
- 基于范围的 for 循环将对象移动到另一个容器中?