2010-07-01 5 views
26

hey je suis à la recherche sont une solution propre à ce problème:en boucle dans deux directions

alt text

je commence la boucle avec i = 0 dans la deuxième étape de la boucle du i = 1, puis i = -1 puis i = 2 ect. Comment programmer avec une boucle for de manière propre?

+0

Puisque vous demandez une implémentation spécifique, quelle langue vous travaillez? –

+0

php ou js serait bien – antpaw

Répondre

11

Si vous ne dérange pas d'avoir la boucle interne apparaissent 3 fois:

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

2 fois avec un if:

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

seule fois, mais avec une expression laide:

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

    f(i); 
} 
+1

merci, j'aime la version "laide expression" le plus :) – antpaw

+0

@antpaw whhhhhyyyyyyyyyy? En plus d'être laide, c'est la plus compliquée et inefficace en termes de traitement. – stinky472

+0

+1. Une autre solution possible, et cela peut même être nécessaire si nous n'avions pas d'accès aléatoire mais seulement un accès bidirectionnel à une liste chaînée, par exemple, utiliser deux itérateurs (l'un décrémente, l'autre s'incrémente et l'accès au premier élément le début). – 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 
} 

Doit faire ce que vous voulez

+0

+1 pour l'élégance dans la forme; vous devrez peut-être extraire do_stuff dans une fonction séparée afin d'éviter la duplication de code, mais sinon c'est plutôt beau. –

+1

+1, pour plus de simplicité –

+0

-1, pour plus de simplicité – mario

5

Chaque boucle, vous semblez ajouter n*(-1)^(n+1), où n est l'étape que vous prenez actuellement, commençant à 1, et commençant à 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 

etc.

A partir de là, cela dépend de ce que la langue que vous souhaitez écrire. Itérer de n = 0 à l'endroit où vous vous arrêtez.

éditer c'est une mauvaise réponse. mais amusant = D

(j'ajouté ce dernier peu parce que dès que je fait que modifier, quelqu'un me downvoted =()

+0

+1 Cela a été ma pensée immédiate pour une réponse aussi bien :) – NibblyPig

3

Voici une implémentation en javascript

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

Hope it helps.

+0

hehe belles compétences :) – antpaw

+0

réduire votre dépendance sur Math en faisant '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

I utilise la fonction sinus:

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

Une modification de la solution de la balle tombante, qui va gérer le cas index 0 sans une condition particulière.

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

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

Il existe un motif pour cette boucle.En regardant sur la ligne de nombre - il va comme:

  • 0 pas en arrière
  • 1 pas en avant
  • 2 pas en arrière
  • 3 pas en avant
  • 4 pas en arrière

Voici une solution: continuez d'incrémenter la taille du pas à chaque itération de la boucle et inversez la direction (avant/arrière) à chaque fois. Continuez d'ajouter à la valeur actuelle.

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

Une autre solution à l'aide generators en JavaScript 1.7 est identique à @ FallingBullet de solution mais plus esthétique à mes yeux :)

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

Dans C. La valeur de N est le total nombre de valeurs dans la séquence que vous souhaitez donner.

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

Juste une addition d'une soustraction et une négation:

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

génère une boucle intérieure:

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

Pour ce que ça vaut la peine, voici ma propre interprétation du problème.

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

Je serais probablement aller avec:

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