2010-07-01 22 views
26

hey sto cercando sono soluzione pulita a questo problema:loop in due direzioni

alt text

avvio il ciclo con i = 0 nella seconda fase del ciclo del i = 1, quindi i = -1 e quindi i = 2 ect.

come programmare questo con un ciclo for in modo pulito?

+0

Dal momento che si chiede una specifica implementazione, che lingua stai lavorando in? –

+0

php o js andrebbe bene – antpaw

risposta

11

Se non ti dispiace avere il ciclo interno appaiono 3 volte:

f(0); 
for (var i = 1; i <= 3; ++ i) { 
    f(i); 
    f(-i); 
} 

2 volte con una if:

for (var i = 0; i <= 3; ++ i) { 
    f(i); 
    if (i > 0) 
    f(-i); 
} 

getta, ma con una brutta espressione:

for (var j = 1; j <= 7; ++ j) { 
    var i = j/2; 
    if (j % 2) i = -i; 

    f(i); 
} 
+1

grazie, mi piace la versione "brutta espressione" più :) – antpaw

+0

@antpaw whhhhhyyyyyyyyy? Oltre ad essere più brutto, è anche il più contorto e inefficiente in termini di elaborazione. – stinky472

+0

+1. Un'altra possibile soluzione, e potrebbe anche essere necessaria se non avessimo accesso casuale, ma solo l'accesso bidirezionale a una lista collegata, ad esempio, è di utilizzare due iteratori (uno viene decrementato, l'altro viene incrementato e l'accesso al primo elemento a l'inizio). – stinky472

27
f(0); //do stuff with 0 

for(var i = 1; i<len; i++) //where len = positive boundary 
{ 
    f(i); //do stuff with i 
    f(-i); //do stuff with -i 
} 

Dovrebbe fare quello che vuoi

+0

+1 per eleganza nella forma; potrebbe essere necessario estrarre do_stuff in una funzione separata per evitare la duplicazione del codice, ma per il resto è piuttosto bello. –

+1

+1, per semplicità –

+0

-1, per semplicità – mario

5

Ogni ciclo, sembra aggiungere n*(-1)^(n+1), dove n è il passo che stai attualmente prendendo, a partire da 1, e partendo da i = 0.

initialize i = 0 
n=0, i+=0*(-1)^1 # 0 
n=1, i+=1*(-1)^2 # 1 
n=2, i+=2*(-1)^3 # -1 
n=3, i+=3*(-1)^4 # 2 

ecc

Da qui, dipende da quale lingua si vorrebbe scrivere. Un'iterazione da n = 0 ovunque siete fermarsi.

modifica questa è una cattiva risposta. ma divertente = D

(ho aggiunto che l'ultimo pezzo perché non appena ho fatto che modificare, qualcuno mi downvoted =()

+0

+1 Questo è stato il mio pensiero immediato per una risposta :) – NibblyPig

3

Qui è la realizzazione in javascript

for (var i = 0; Math.abs(i)<10; i=(i<=0?Math.abs(i)+1:-i)) { 
    console.debug(i) 
} 

Speranza che aiuta.

+0

hehe nice skills :) – antpaw

+0

ridurre la dipendenza da Math facendo 'i = 0; i <10;i=(i<=0> 1-i: -i)' – fbstj

1
 for (int i = 0; i < 10; i++) 
     { 
      int div = i/2; 
      int mod = i % 2; 

      int offset = mod == 0 ? div : -div; 
     } 
2

ho usato la funzione seno:

for ($i = 0; $i < 10; $i++) 
{ 
    echo round(0.5 * $i * sin((0.5 + $i) * M_PI))."\n"; 
} 
0

Una modifica della soluzione del proiettile che cade, che gestirà il caso dell'indice 0 senza una condizione speciale.

//do stuff with 0 
for(int i = 0; i< (arrayLength/2); i++) 
{ 
    //do stuff with i 

    if(-i != i) 
    { 
     //do stuff with negIndex 
    } 
} 
1

C'è un motivo per questo ciclo.Guardando sulla linea numero - va come:

  • 0 passi indietro
  • 1 passo avanti
  • 2 passi indietro
  • 3 passi avanti
  • 4 passi indietro

Ecco una soluzione: continua ad incrementare la dimensione del passo in ogni iterazione del ciclo e capovolgi la direzione (avanti/indietro) ogni volta. Continua ad aggiungere al valore corrente.

// n is the number of elements to generate 
for(var i = 0, value = 0, dir = -1; i < n; i++) { 
    value = value + (dir * i); 
    console.log(value); 
    dir = dir * -1; // reverse direction 
} 

Un'altra soluzione utilizzando generators in JavaScript 1.7, che è identica a quella di @solution FallingBullet ma esteticamente più gradevole al mio occhio :)

function sequence() { 
    var i = 0; 

    yield i; 

    while(true) { 
     i++; 
     yield i; 
     yield -i; 
    } 
} 


var seq = sequence(); 
seq.next(); // 0 
seq.next(); // 1 
seq.next(); // -1 
seq.next(); // 2 
... 
0

in C. Il valore di N è il totale numero di valori nella sequenza che desideri cedere.

int i, n = 0, m = 1; 
for (i = 1; i < N; i++, m = -m) { 
    /* n is the next in the sequence */ 
    n += m * i; 
} 
3

Solo uno più uno sottrazione e una negazione:

for(int i=0, d=1, f=-1; i<10; i+=d, d=f-d, f=-f) 
{ 
    printf("%d\n", i); 
} 

genera un ciclo interno di:

push  esi 
push  offset string "%d\n" (0D20F4h) 
call  dword ptr [__imp__printf (0D20A4h)] 
mov   eax,ebx 
add   esi,edi 
sub   eax,edi 
add   esp,8 
neg   ebx 
mov   edi,eax 
cmp   esi,0Ah 
jl   wmain+10h (0D1010h) 
1

Per quello che vale, ecco la mia personale interpretazione del problema.

for (var i = 0; i > -8; i = (i<=0) - i) // arbitrary condition stops loop at -8 
0

probabilmente sarei andare con:

for (var i = 0; i <= max; i = (i <= 0) ? -i + 1 : -i) 
{ 
    f(i); 
} 
Problemi correlati