Пройдите массив вперед и назад - PullRequest
0 голосов
/ 30 октября 2018

У нас есть массив некоторой длины (скажем, 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]+" ");
        }
    }

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Это решение вычисляет индекс arr только из i, что позволяет избежать необходимости сохранять какое-либо состояние (например, текущее направление). В результате это немного более запутанно, но также будет работать для непоследовательных значений 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 при повторном движении вперед.

Другими словами, циклы прямого и обратного пропускают один индекс, чтобы избежать повторения при изменении направления, следовательно, CYCLE = LENGTH - 1, что также означает, что LENGTH должно быть не менее 2, чтобы избежать деления на ноль.

0 голосов
/ 30 октября 2018

Может быть, что-то вроде этого:

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