简体   繁体   English

有没有一种方法可以创建一个奇特的迭代器和相应的新数组,以便检查每个索引的索引值条件?

[英]Is there a way to create a fancy iterator & corresponding new array such that a condition is checked on index value for each index?

In C++, is there a way to create a new array from an old array with the old array only having those values from indices that satisfy a condition? 在C ++中,是否有一种方法可以从旧数组创建新数组,而旧数组仅具有满足条件的索引中的值?

For instance, say we have 例如,说我们有

float A[10] ;    

and the indices, in this case, are idx=0,1,2,3,4,5,6,7,8,9. 在这种情况下,索引为idx = 0,1,2,3,4,5,6,7,8,9。

I'd like to iterate, in a single-pass over these indices, checking a condition, say 我想一次遍历这些索引来检查条件,例如

idx >0 && idx < 8  

and so I obtain a new float array, say 所以我得到一个新的float数组

float B[8]    

Numbered just the way you'd expect, idx_new=0,1,2,3,4,5,6,7, but only having the values from A of A[1], A[2],.. A[7]. 以您期望的方式编号,idx_new = 0、1、2、3、4、5、6、7,但仅具有A [1],A [2],.. A [7]中A的值]。

I ask this because in the problem I'm working on, I have a 2-dimensional so-called "staggered grid", laid out in a 1-dimensional float array, and I want a new array with only the "inner cells." 我之所以这样问是因为,在我正在研究的问题中,我有一个二维的所谓“交错网格”,以一维浮点数组的形式布置,并且我想要一个仅包含“内部单元格”的新数组。 “ For example, I begin with a 5x6 staggered grid. 例如,我从5x6交错网格开始。 It's represented by a float A[30] array of 30 floats. 它由30个浮点数的浮点数A [30]数组表示。 I can imagine this A to be a 2 dimensional grid with x-coordinate x=O,1,2,3,4 and y-coordinate y=0,1,2,3,4,5. 我可以想象这个A是一个二维网格,x坐标x = O,1,2,3,4,y坐标y = 0,1,2,3,4,5。 I can access it's value on A through the (arithmetic) formula x+5*y, ie 我可以通过(算术)公式x + 5 * y访问A的值,即

A[x+5*y] ; // gets the value I want  

But now, I want a new array of only "inner cells" that excludes the grid points along the 4 "walls." 但是现在,我想要一个只包含“内部单元”的新数组,该数组不包括沿4个“墙”的网格点。 So 0< x' < 4 and 0 所以0 <x'<4和0

Advice and discussions on how to implement this, utilizing good C++11/14 practices and fancy iterators, functors, and general advice on how to approach this kind of problem with the new features from C++11/14, would help me. 利用良好的C ++ 11/14做法以及精美的迭代器,函子以及如何使用C ++ 11/14的新功能解决此类问题的一般建议,就如何实现此建议和讨论提供了帮助。

Posting here in stackoverflow helped because, believe me, I searched on Google many search term permutations for the question I had originally asked, but the suggestions ** std::transform ** and ** std::copy_if ** (thanks to @jwimberley but he/she deleted his/her original answer, but std::copy_if helped alot) helped greatly in what to search for (use of std::copy_if isn't "advertised" enough, probably). 在这里,在stackoverflow中发布内容很有帮助,因为,相信我,我在Google上搜索了许多搜索字词排列,以查找最初提出的问题,但是建议** std::transform **和** std::copy_if **(感谢@ jwimberley,但他/她删除了他/她的原始答案,但是std::copy_if copy_if很有帮助)在搜索内容方面std::copy_if大的作用(可能对std::copy_if使用不够“宣传”)。

Those Google searches led me to @Mikhail 's answer, which is exactly what I needed, to take a subset of an array, to make a new array. 那些Google搜索使我得到@Mikhail的答案,这正是我需要的答案,它可以使用数组的一个子集来创建一个新的数组。 cf. 比照 How to obtain index of element from predicate passed to some STL algorithm? 如何从传递给某些STL算法的谓词中获取元素的索引?

Given these arrays/vectors (I'm filling up "boilerplate", test values: 给定这些数组/向量(我正在填写“样板”,测试值:

float A[10] { 11.,22.,33.,44.,55.,66.,77.,88.,99.,100.};
float B[8] = { 0. };
std::vector<float> A_vec(A,A+10);
std::vector<float> B_vec(B,B+8);  

then this is the important step: 这是重要的步骤:

auto iter = std::copy_if( A_vec.begin(), A_vec.end(), B_vec.begin(), 
   [&A_vec] (const float& x) -> bool { // <-- do not forget reference here
    size_t index = &x - &A_vec[0]; // simple, "textbook" manner to get the index
    std::cout << index << " ";
    bool condition = ((index >0) && (index <9));
    return condition; } );

which results in, for B_vec 结果是,对于B_vec

// [ 22 33 44 55 66 77 88 99 ] // success!  

For the application I had, from going from a staggered grid to its inner cells, I did this - given 对于我的应用程序,从交错网格到其内部单元,我做到了-给定

std::vector<float> staggered_grid(5*6) ; // 30 elements, each initialized to 0;
std::vector<float> inner_cells(3*4  ); // 12 elements, each initialized to 0   

for (int idx=0; idx<5*6;++idx) {
     staggered_grid[idx] = ((float) idx+10.f) ;}

and so the important step is 所以重要的一步是

auto iter2d = std::copy_if( staggered_grid.begin(), staggered_grid.end(), inner_cells.begin(), 
[&] (const float& x) -> bool {          // <- do not forget reference here
       size_t index = &x - &staggered_grid[0]; // simple, "textbook" manner to get the index
       int j = index/5;
       int i = index % 5;
       bool condition = ((i>0) && (i<5-1) && (j>0) && (j<6-1));
       return condition; } );   

and so the result was 所以结果是

10 11 12 13 14 10 11 12 13 14
15 16 17 18 19 15 16 17 18 19
20 21 22 23 24 20 21 22 23 24
25 26 27 28 29 25 26 27 28 29
30 31 32 33 34 30 31 32 33 34
35 36 37 38 39 35 36 37 38 39

-> - >

16 17 18 16 17 18
21 22 23 21 22 23
26 27 28 26 27 28
31 32 33 31 32 33

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM