Итерация массива, начинающаяся с середины

StackOverflow https://stackoverflow.com/questions/1616854

  •  06-07-2019
  •  | 
  •  

Вопрос

В недавнем интервью был задан один странный вопрос

a[]= { 1,2,3,4,5,6,7,8,9,10}

Когда задается массив с указанным начальным индексом, я должен повторять его, пока не пройду все элементы.

Я имею в виду, предположим, что начальный индекс равен "5", с которого я должен начать 6,7,8,9,10,5,4,3,2,1.Пожалуйста, внимательно посмотрите на последовательность, как можно создать Reset(), Current, бла-бла-бла ...?.

Но интервьюер выполнил последовательность действий, как он просил.Он не показал код.

Можем ли мы действительно разработать логику для такого странного требования?

Это было полезно?

Решение

Просто используйте две петли.

IEnumerable<int> ForwardsBackwards(int[] a, int start) {
    for(int i=start; i<a.Length; i++) 
        yield return a[i];
    for(int i=start-1; i>=0; i--) 
        yield return a[i];
}

Редактировать:Еще лучше с linq:

IEnumerable<int> ForwardBackward(int[] a, int start) {
    return a.Skip(start).Concat(a.Take(start).Reverse());
}

Другие советы

Проще в обслуживании (?):

        int[] a= {1,2,3,4,5,6,7,8,9,10};

        int StartIndex=5;

        for (int iCount = StartIndex; iCount < a.Count() + StartIndex; iCount++)
        {
            Debug.WriteLine(a[(iCount + a.Count()) % a.Count()]);
        }

Результат равен:

6 7 8 9 10 1 2 3 4 5

Редактировать:только что заметил вашу последовательность, она меняется на противоположную, когда вы достигаете верхнего предела.Это было бы неприятно, если бы это был заданный вопрос.

Это старая тема, но мне нужен был тот же алгоритм, и я пришел к хорошему решению.Решение

  1. Может начинаться с ЛЮБОГО элемента массива
  2. Может начать итерацию в ЛЮБОМ направлении
  3. Пройдем все элементы, начиная со СЛЕДУЮЩЕГО по направлению движения
  4. Будет перекрываться с первым / последним, когда будет достигнут пограничный элемент

Вся магия находится в одной линии с для оператор цикла, другой код предназначен для удобства предварительного просмотра.

// Example program
#include <iostream>
#include <string>

int a[] = {0,1,2,3,4,5};
int Count = sizeof(a)/sizeof(int);

void LoopFromMidWithDirection ( int curIdx , int motion )
{
    std::cout << "\nNextFrom=" << curIdx << " motion =" << motion << "\n";
    curIdx +=motion;
    for (int i = curIdx; (i - curIdx) * motion < Count ; i += motion)
        std::cout << a[(i + Count) % Count] << " ";

    std::cout << "\n";
}

int main()
{
    LoopFromMidWithDirection(4, +1);
    LoopFromMidWithDirection(6, +1);
    LoopFromMidWithDirection(0, -1);
}

Выходной сигнал

NextFrom=4 motion =1
5 0 1 2 3 4 

NextFrom=6 motion =1
1 2 3 4 5 0 

NextFrom=0 motion =-1
5 4 3 2 1 0 

Решение вдохновлено @Neil Kimber

Да, вы должны внедрить IEnumerator интерфейс на пользовательский класс. Запишите логику в метод MoveNext, который обнаруживает конец массива, а затем запускается в начале массива, помня промежуточную начальную точку.

Следуйте этим образцам кода от Microsoft как шаблон.

(DEFINE (traverse length start call) 
  (DEFINE (flow index motion)
    (cond ((> index length) 
              (flow (- start 1) -1))
          ((> index -1) 
              ((call index) (flow (+ index motion) motion)))))
  (flow start +1))

(traverse 9 5 job)

Мне нравится 9 к 5 аспекту вопроса. Интересно, они намекали на что-то? Если предположить, что job распечатывает индекс массива, это приведет к 678954321.

В C я бы соблазнился использовать цикл for (а не цикл while, как у меня был до редактирования);

int a[]= { 1,2,3,4,5,6,7,8,9,10};
int length = 10;
int start = 5;
int motion = 1; //increment

for( int index = start; index >= 0; index += motion ) {
  if(index > (length-1)) {
    motion = -1; //decrement
    index = start -1;
  else {
    printf("%d", a[index]);
  }
}

Процесс завершается только после печати нулевого индекса. Единственный раз, когда вы не пересекаете массив, это когда вы его превышаете. Когда это произойдет, вы вернетесь к начальному индексу (-1) и поменяете местами движение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top