Domanda

In una recente intervista è stata posta una domanda particolare

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

Quando viene dato un array con l'indice iniziale specificato, devo iterarlo fino a quando non lo percorro tutti gli elementi.

Voglio dire, suppongo che l'indice di partenza sia "5". devo iniziare da 6,7,8,9,10,5,4,3,2,1 . Si prega di guardare attentamente la sequenza, come si può creare Reset (), Corrente, bla, bla ...?.

Ma l'intervistatore ha eseguito la sequenza su sua richiesta. Non ha mostrato il codice.

Possiamo davvero sviluppare una logica per un requisito così strano?

È stato utile?

Soluzione

Usa solo due loop.

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

Modifica: Ancora meglio con linq:

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

Altri suggerimenti

Più facile da mantenere (?):

        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()]);
        }

L'output è:

6 7 8 9 10 1 2 3 4 5

Modifica: appena individuato la sequenza, si inverte quando si raggiunge il limite superiore. È brutto se questa fosse la domanda specificata.

È un vecchio thread, ma avevo bisogno dello stesso algoritmo e ho trovato una buona soluzione. Soluzione

  1. Può iniziare da QUALSIASI elemento dell'array
  2. Può iniziare iterare in QUALSIASI direzione
  3. Passerà tutti gli elementi, a partire da NEXT nella direzione del movimento
  4. Si sovrapporranno al primo / ultimo, quando viene raggiunto l'elemento bordo

Tutta la magia è in linea singola con per l'operatore del ciclo, l'altro codice è per comodità dell'anteprima.

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

Output

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 

La soluzione è ispirata a @Neil Kimber

Sì, è necessario implementare IEnumerator interfaccia su una classe personalizzata. Scrivi la logica nel metodo MoveNext che rileva la fine dell'array e quindi inizia all'inizio dell'array, ricordando il punto iniziale a metà strada.

Segui questi esempi di codice di Microsoft as un modello.

(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)

Mi piace l'aspetto da 9 a 5 della domanda. Mi chiedo se stessero alludendo a qualcosa? Supponendo che job stia stampando l'indice dell'array, questo produrrebbe 678954321.

In C sarei tentato di usare un ciclo for (non un ciclo while come lo avevo prima della modifica);

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

Il processo è terminato solo dopo aver stampato l'indice zero. L'unica volta che non stai attraversando l'array è quando lo hai superato. Quando ciò accade, si ritorna all'indice iniziale (-1) e si inverte il movimento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top