1

不完全确定如何命名,但我希望它有意义。我想向前迭代一个数组,然后向后迭代 x 次。一种选择是将数组的大小加倍,然后根据 mod 长度进行迭代,从而以循环方式进行迭代。假设一个非常大的序列,这可能会消耗大量不必要的内存。另一种选择是:

while(++i <= iterations) {
    for(j = 0; j < arrayLength; j++){
        //do something
    }
    for(j = arrayLength - 1; j >= 0; j--){
        //do something
    }
}

但这感觉很丑 - 我有点重复自己,只是切换 ++/--。我正在寻找一种优雅的编码方法。语言应该是 C 或 C++。为了非常清楚,我正在寻找一种不同的算法。谢谢。

4

5 回答 5

2

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 */ ;
}

在 C++14 中,我们还会有std::rbeginandstd::rend,所以你可以编写如下内容:

auto rb = std::rbegin(array);
auto re = std::rend(array);
while (rb != re) {
    // do something
    ++rb;
}

也就是说,如果您正在使用普通数组。大多数标准容器已经附带了为您提供反向迭代器rbegin()rend()方法。

于 2013-06-03T20:13:39.037 回答
1

好吧,这是一种不同的方法。不过,不会声称根据任何特定标准它一定会更好。

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;
}

我实际上认为这有点令人费解,并且等待发生的维护噩梦,但至少你没有“重复自己”。它可能是“聪明”意义上的“优雅”……而不是“简单”意义上的“优雅”。

于 2013-06-03T20:33:10.590 回答
1

这以牺牲一些效率为代价提供了优雅:

while(++i <= iterations) {
    for(j = 0; j < twiceArrayLength; ++j) {
        k = min(j, arrayLengthMinusOne) - max(0, j - arrayLength);
        doSomething(k);
    }
}

示例:当arrayLength为时5j则从09,对应的值k从上到下0到。440

编辑:根据您的要求,要从数组中的不同点开始,您可以这样做:

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);
    }
}
于 2013-06-03T20:38:42.357 回答
0

也许稍微好一点?

j = -1;

while(++i <= iterations) {
    while(++j < arrayLength){
        //do something
    }
    while(--j >= 0){
        //do something
    }
}

或者,您可以对元素进行一致的操作吗?

while(++i <= iterations) {
    for(j = 0; j < arrayLength; j++){
        //do something with array[j]
        //do something with array[arrayLength - j - 1]
    }
}
于 2013-06-03T19:55:58.177 回答
0
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 }

}
于 2013-06-03T20:02:14.847 回答