[英]Iterating An Array Symmetrically
Wasn't exactly sure how to title this, but I hope it makes sense. 不确定如何标题,但我希望它有意义。 I want to iterate an array forwards and then backwards, x number of times. 我想向前迭代一个数组,然后向后迭代x次。 One option is to double the size of the array and then iterate based on mod length, thus iterating in a circular fashion. 一种选择是使数组的大小加倍,然后基于模长度迭代,从而以循环方式迭代。 Assuming an extremely large sequence, that could consume a lot of unnecessary memory. 假设序列非常大,可能会占用大量不必要的内存。 Another option is this: 另一种选择是:
while(++i <= iterations) {
for(j = 0; j < arrayLength; j++){
//do something
}
for(j = arrayLength - 1; j >= 0; j--){
//do something
}
}
That just feels ugly though - I'm sort of repeating myself, just switching the ++/--. 这只是感觉很难看 - 我有点重复自己,只是改变++ / - 。 I'm looking for an elegant coding approach to this. 我正在寻找一种优雅的编码方法。 The language should be C or C++. 语言应该是C或C ++。 Just to be very clear, I'm looking for a different algorithm. 为了清楚起见,我正在寻找一种不同的算法。 Thanks. 谢谢。
boost::adaptors::reverse
could come handy here: boost::adaptors::reverse
可以派上用场:
#include <boost/range/adaptors.hpp>
while (i++ < iterations) {
for (auto i : array) /* do something */ ;
for (auto i : boost::adaptors::reverse(array)) /* do something */ ;
}
In C++14, we'll also have std::rbegin
and std::rend
, sou you could write something like: 在C ++ 14中,我们还将有std::rbegin
和std::rend
,你可以这样写:
auto rb = std::rbegin(array);
auto re = std::rend(array);
while (rb != re) {
// do something
++rb;
}
That is if you're working with plain arrays. 那就是你正在使用普通数组。 Most of standard containers already come with rbegin()
and rend()
methods that give you reverse iterators. 大多数标准容器已经附带了rbegin()
和rend()
方法,可以为您提供反向迭代器。
Well, here's a different approach. 嗯,这是一个不同的方法。 Not going to claim it's necessarily better by any particular criteria, though. 但是,根据任何特定标准,不会声称它必然更好。
int dir = 1;
int start = 0, end = arrayLength - 1;
while (++i <= (iterations << 1))
{ int j = start;
do
{ // something
j += dir;
} while (j != end);
dir = -dir;
int tmp = start; start = end; end = tmp;
}
I actually think that's a bit convoluted, and a maintenance nightmare waiting to happen, but at least you're not "repeating yourself". 我实际上认为这有点令人费解,维护噩梦等待发生,但至少你不是“重复自己”。 And it might be "elegant" in the "clever" sense... Not so much in the "simple" sense. 它可能在“聪明”的意义上是“优雅的”......在“简单”意义上并非如此。
This gives elegance at the cost of some efficiency: 这样可以提高效率:
while(++i <= iterations) {
for(j = 0; j < twiceArrayLength; ++j) {
k = min(j, arrayLengthMinusOne) - max(0, j - arrayLength);
doSomething(k);
}
}
Example: When arrayLength
is 5
, then j
will run from 0
to 9
, and the corresponding value of k
will run from 0
up to 4
and then from 4
down to 0
. 示例:当arrayLength
为5
, j
将从0
运行到9
,并且相应的k
值将从0
到4
运行,然后从4
到0
。
EDIT: As per your request, to start at a different point in the array, you can do this: 编辑:根据您的要求,从阵列中的不同点开始,您可以这样做:
while(++i <= iterations) {
endPoint = startPoint + twiceArrayLength;
for(j = startPoint; j < endPoint; ++j) {
jModTwiceArrayLength = j % twiceArrayLength;
k = min(jModTwiceArrayLength, arrayLengthMinusOne) - max(0, jModTwiceArrayLength - arrayLength);
doSomething(k);
}
}
Perhaps slightly nicer? 也许稍好一点?
j = -1;
while(++i <= iterations) {
while(++j < arrayLength){
//do something
}
while(--j >= 0){
//do something
}
}
Alternatively, can you operate on the elements in unison? 或者,您可以同时对元素进行操作吗?
while(++i <= iterations) {
for(j = 0; j < arrayLength; j++){
//do something with array[j]
//do something with array[arrayLength - j - 1]
}
}
while(++i <= iterations)
{
for(auto it = array.begin(); it!=array.end(); ++it)
{ //do something }
for(auto it = array.rbegin(); it!=array.rend(); ++it)
{ //do something }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.