来回遍历数组

Go through the array back and forth

我们有一个长度为 3 的数组和一些计数序列:0,1,2,3,4,... 到无穷大。从该输入序列中,我们需要生成将来回遍历数组的序列,例如:0,1,2,1,0,1,2,1,0,... 等等 length=3.

我认为这个任务在很多编程书籍中都是很常见的任务,但是我找不到标准的解决方案,所以我创建了自己的解决方案。有没有其他更有效和优雅的解决方案,因为我不喜欢我的解决方案???

#define LENGTH 5
int main()
{
   char arr[LENGTH] = {'a','b','c','d','e'};
   int i;
   int base=0;
   for(i=0;i<100;i++){ 
        if(i%(LENGTH-1)==0){ 
            if(base==0) base=LENGTH-1;
            else base =0;
        }
    int j = abs(base-i%(LENGTH-1)); 
    printf("%c ",arr[j]); 
   }
}

Java 代码(为方便起见):

public static void traverse(){
        char arr[] = {'a','b','c','d','e'};
        int base=0;
        for(int i=0;i<100;i++){ 
            if(i%(arr.length-1)==0){ 
            if(base==0) base=arr.length-1;
            else base =0;
            }
        int j = Math.abs(base-i%(arr.length-1)); 
        System.out.println(arr[j]+" ");
        }
    }

也许是这样的:

#define LENGTH 5
int main()
{
    char arr[LENGTH] = { 'a','b','c','d','e' };
    int current = 0;
    int direction = 1;
    for (int i = 0; i < 100; i++) 
    {       
        printf("%c ", arr[current]);
        if (current == 0)
            direction = 1;
        else if (current == LENGTH - 1)
            direction = -1;
        current += direction;
    }
}

该解决方案仅从i计算arr的索引,从而避免需要保持任何状态(例如当前方向)。结果它有点复杂,但也适用于 i.

的非连续值
char arr[] = { '0', '1', '2', '3', '4' };
const int LENGTH = sizeof arr / sizeof(*arr); // not necessary for char
assert(LENGTH > 1); // doesn't work for fewer than 2 elements

const int CYCLE = LENGTH - 1;
for (int i = 0; i < 100; ++i) { 
    printf("%c ", arr[ (i / CYCLE) & 1 ? CYCLE - i % CYCLE : i % CYCLE ]);
}
printf("\n");

说明:i / CYCLE为数组循环的次数,& 1检查该数的最低有效位来确定方向(奇数循环,该位为1向后, 偶数循环——从 0 开始——向前)。 i % CYCLE 是向前循环,但是由于CYCLE = LENGTH - 1,它没有到达数组的最后一个索引。 CYCLE - i % CYCLE为倒退循环,从CYCLE - 0开始,也就是前进时最后一个没有到达的索引,到1结束,这样就避免了重复索引0 ] 再次前进时

换句话说,forward和backward循环都省略了一个索引,以避免在改变方向时重复,因此CYCLE = LENGTH - 1,这也意味着LENGTH必须至少是2 以避免被零除。