2010-07-01 12 views
26

bueno que estoy buscando son solución limpia a este problema:bucle en dos direcciones

alt text

empiezo el lazo con i = 0 en el segundo paso de bucle del i = 1, entonces i = -1 y luego i = 2 ect.

cómo programar esto con un bucle for de una manera limpia?

+0

que lo preguntas para una aplicación específica, ¿qué idioma está trabajando en? –

+0

php o js estaría bien – antpaw

Respuesta

11

Si no te importa tener el bucle interno Parece que 3 veces:

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

2 veces con un if:

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

tiempo sola, pero con una expresión fea:

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

    f(i); 
} 
+1

gracias, me gusta la versión "fea expresión" más :) – antpaw

+0

@antpaw whhhhhyyyyyyyyy? Además de ser el más feo, es el más complicado e ineficiente también en términos de procesamiento. – stinky472

+0

+1. Otra solución posible, y esto incluso puede ser necesario si no tuviéramos acceso aleatorio pero solo acceso bidireccional a una lista vinculada, por ejemplo, usar dos iteradores (uno se reduce, otro se incrementa, y se accede al primer elemento en el principio). – 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 
} 

Haga lo que desee

+0

+1 por elegancia en la forma; Es posible que tenga que extraer do_stuff en una función separada para evitar la duplicación de código, pero de lo contrario es muy bonito. –

+1

+1, por simplicidad –

+0

-1, por simplicidad – mario

5

Cada ciclo, parece que está agregando n*(-1)^(n+1), donde n es el paso que está tomando actualmente, comenzando en 1 y comenzando en 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 aquí, que depende de qué idioma en el que desea escribir. Iterar de n = 0 a donde está parando.

editar esto es una mala respuesta. pero divertido = D

(I añadió que el último bit porque tan pronto como hice esa edición, alguien me downvoted =()

+0

1 Este fue mi primer pensamiento para una respuesta tan bien :) – NibblyPig

3

Aquí es la implementación en javascript

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

espero que ayude.

+0

jeje :) buenas habilidades – antpaw

+0

reducir su dependencia de las matemáticas haciendo '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

he utilizado la función seno:

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

Una modificación de la solución de caída de bala, que manejará el caso índice 0 sin una condición especial.

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

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

Hay un patrón en este circuito.Mirando en la línea número - va como:

  • 0 pasos hacia atrás
  • 1 paso adelante
  • 2 pasos hacia atrás
  • 3 pasos hacia adelante
  • 4 pasos hacia atrás

Aquí hay una solución: siga incrementando el tamaño del paso en cada iteración del bucle, y la dirección del giro (hacia adelante/hacia atrás) cada vez. Sigue agregando al valor actual.

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

Otra solución usando generators en JavaScript 1.7 que es idéntico al de @solution FallingBullet pero más estéticamente agradable para el ojo :)

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

En C. El valor de N es el total de número de valores en la secuencia que desea ceder.

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

Sólo una adición de un resta y una negación:

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

genera un bucle interno de:

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

Por lo que vale la pena, que aquí es mi propia interpretación del problema.

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

probablemente iría con:

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