iteração matriz a partir do meio
Pergunta
Em uma entrevista recente a uma pergunta peculiar foi convidado
a[]= { 1,2,3,4,5,6,7,8,9,10}
Quando uma matriz é dado com o índice inicial especificado i tem a iterar lo até i transversal todos os elementos.
Quer dizer suponha que o índice inicial é "5" i tem que começar do 6,7,8,9,10,5,4,3,2,1
.Please observar atentamente a seqüência, como se pode criar Reset (),
Atual, blá, blá ...?.
Mas o entrevistador executada a seqüência como ele asked.He não mostrar o código.
Podemos realmente desenvolver uma lógica de uma exigência tão estranha?
Solução
Basta usar dois loops.
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];
}
Edit: Ainda melhor com LINQ:
IEnumerable<int> ForwardBackward(int[] a, int start) {
return a.Skip(start).Concat(a.Take(start).Reverse());
}
Outras dicas
Mais fácil de manter (?):
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()]);
}
A saída é:
6 7 8 9 10 1 2 3 4 5
Editar: só viu sua seqüência, inverte quando você atingir o limite superior. Isso é desagradável se essa era a pergunta especificada.
É uma discussão antiga, mas eu tinha necessidade de mesmo algoritmo, e chegou a uma solução agradável. Solução
- Pode começar a partir de qualquer elemento do array
- Pode começar iterate para qualquer direção
- Vai passar todos os elementos, a partir do próximo na direção do movimento
- Será que se sobrepõem ao primeiro / último, quando o elemento de fronteira é atingido
Toda a magia está em linha única com operador de loop, outro código é para a conveniência de visualização.
// 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);
}
saída
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
Solution é inspirado @Neil Kimber
Sim, você deve implementar o IEnumerator interagir em uma classe personalizada. Escrever lógica para o método MoveNext que detecta o fim da série e, em seguida, começa no início da matriz, lembrando o ponto a meio caminho início.
Siga estes exemplos de código pela Microsoft como um modelo.
(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)
Eu gosto do 9-5 aspecto da questão. Eu me pergunto se eles foram aludindo a alguma coisa? Assumindo gravuras job
o índice de matriz, isso produziria 678954321.
Em C eu seria tentado a usar um loop for (não um loop while como eu tinha antes de edição);
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]);
}
}
O processo é só terminou depois de imprimir o índice zero. A única vez que você não está atravessando a matriz é quando você excedeu-lo. Quando isso acontece, você retornar ao índice inicial (-1) e inverter o movimento.