[英]Iterating over a column of a multidimensional array with std::count_if()?
I have a multidimensional array of type double ( double someArray[10][20]
).我有一个 double 类型的多维数组( double someArray[10][20]
)。 I'd like to:我想:
a) use std::count_if()
to iterate over a single column of that array, returning the number of values greater than some number a) 使用std::count_if()
迭代该数组的单列,返回大于某个数字的值的数量
b) also require that the row index of that number is within a certain range. b) 还要求该数字的行索引在一定范围内。
I know the basics of using std::count_if
(ie I know how to iterate over, say, some vector and return values greater than/less than/equal to some value, for example), but I'm not sure how to do this over a column of a multidimensional array, or how to check that the index of the element also satisfies some condition.我知道使用std::count_if
的基础知识(例如,我知道如何迭代某些向量并返回大于/小于/等于某个值的值),但我不知道该怎么做this 在多维数组的一列上,或者如何检查元素的索引是否也满足某些条件。
If you are willing to use boost::range , you can use the count_if
with a stride count.如果您愿意使用boost::range ,则可以使用带有步幅计数的count_if
。
The reason why this will work is that an array, regardless of the number of dimensions, will store its data in contiguous memory, thus random-access iteration will work exactly as it would a one-dimensional array.这将起作用的原因是,无论维数如何,数组都将其数据存储在连续内存中,因此随机访问迭代将与一维数组完全一样工作。
Thus the goal is to figure out the starting column (easy), and instead of iterating one element at a time forward as you would with the "normal" std::count_if
, you want to iterate (in your case) 20
elements, since iterating that many will take you to the next row of the column you're interested in.因此,目标是找出起始列(简单),而不是像使用“正常” std::count_if
那样一次迭代一个元素,而是要迭代(在您的情况下) 20
元素,因为迭代许多将带您到您感兴趣的列的下一行。
For a 2D array of M x N
size, the starting and ending addresses you would use for the STL algorithm functions would be:对于M x N
大小的二维数组,用于 STL 算法函数的起始地址和结束地址将是:
start: &array2D[0][0]
end (one item passed the end): &array[M-1][N]
Given this information, here is an example using boost
:鉴于此信息,以下是使用boost
的示例:
#include <boost/range/adaptor/strided.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm.hpp>
#include <algorithm>
#include <iostream>
#include <numeric>
int main()
{
using namespace boost::adaptors;
using namespace boost::assign;
// declare and fill in the array with numbers starting from 0
double someArray[10][20];
std::iota(&someArray[0][0], &someArray[9][20], 0.0);
// let's get the address of the start of the third column
const double* startAddr = &someArray[0][2];
// here is the address of the end of the 2-dimensional array
const double* endAddr = &someArray[9][20]; // add up the third column
// create a SinglePass range consisting of the starting and ending address
// plus the stride count
auto str = std::make_pair(startAddr, endAddr) | strided(20);
// count how many items in the third column are less than 60
auto result = boost::range::count_if(str, [&](double val) { return val < 60; });
std::cout << result;
}
Output:输出:
3
Divide and conquer.分而治之。
count_if
to iterate over a single column of a multidimensional array, checking that the index of the row is within a certain range.使用count_if
迭代多维数组的单列,检查该行的索引是否在一定范围内。Break the problem into smaller pieces, until they are small enough to solve.将问题分解成更小的部分,直到它们小到可以解决为止。
count_if
使用count_if
Hmm... that first task looks doable.嗯……第一个任务看起来可行。 Maybe the last.也许是最后。 Back to division.回到分区。
std::count_if
使用std::count_if
Iterating over an array is not hard, given std::begin
and std::end
.鉴于std::begin
和std::end
,迭代数组并不难。 The multidimensional aspect looks scary, so let's wait on that and see how far we can get.多维方面看起来很可怕,所以让我们拭目以待,看看我们能走多远。 For now, just plug "iterate over an array" into "use count_if
".现在,只需将“迭代数组”插入“使用count_if
”。
std::count_if(std::begin(someArray), std::end(someArray), [](auto & element)
{ return ???; });
Hmm... the name element
is not accurate is it?嗯...名称element
不准确是吗? When std::begin
is applied to double [][20]
, only one dimension is consumed.当std::begin
应用于double [][20]
,只消耗一维。 The result of de-referencing is not double
but double [20]
, so row
would be a more accurate name.取消引用的结果不是double
而是double [20]
,因此row
将是一个更准确的名称。
std::count_if(std::begin(someArray), std::end(someArray), [](auto & row)
{ return ???; });
The multidimensional aspect might have just taken care of itself.多维方面可能刚刚照顾好自己。 Can we focus on just one column?我们可以只关注一栏吗? Let's assume a variable named column
is the desired column index, and target
can be the "some number" from the problem description.让我们假设一个名为column
的变量是所需的列索引,而target
可以是问题描述中的“某个数字”。
std::count_if(std::begin(someArray), std::end(someArray), [column, target](auto & row)
{ return row[column] > target; });
So that leaves restricting the row index to a certain range.这样就可以将行索引限制在某个范围内。 That is, iterate over the restricted range instead of over the entire array.也就是说,迭代受限范围而不是整个数组。 Looks like a job for std::next
and std::prev
.看起来像是std::next
和std::prev
。 We'll just need two more variables to give us the range;我们只需要另外两个变量来为我们提供范围; let's use from
and to
.让我们使用from
和to
。
// Check only the desired rows
auto start = std::next(std::begin(someArray), from);
auto stop = std::prev(std::end(someArray), 9 - to);
return std::count_if(start, stop, [column, target](auto & row)
{ return row[column] > target; });
(I don't like that magic number 9
. Better would be ROWS-1
, assuming suitable constants have been declared so that the array's declaration can become double someArray[ROWS][COLS]
.) (我不喜欢那个神奇的数字9
。最好是ROWS-1
,假设已经声明了合适的常量,以便数组的声明可以变成double someArray[ROWS][COLS]
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.