2010-07-01 3 views
26

эй Я ищу чистые решения этой проблемы:зацикливания в двух направлениях

alt text

я запустить цикл с i = 0 на втором этапе петлевого i = 1, затем i = -1 и затем i = 2 ЭСТ.

Как программировать это с помощью цикла for в чистом виде?

+0

Поскольку вы просите конкретной реализации, на каком языке вы работаете в? –

+0

php или js будет хорошо – antpaw

ответ

11

Если вы не против того, внутренний цикл появляется в 3 раза:

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

2 раза с if:

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

один раз, но с уродливым выражением:

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

    f(i); 
} 
+1

спасибо, мне нравится версия «уродливого выражения» больше всего :) – antpaw

+0

@antpaw whhhhhyyyyyyyyyy? Помимо того, что он является самым уродливым, он является самым запутанным и неэффективным с точки зрения обработки. – stinky472

+0

+1. Другое возможное решение, и это может потребоваться даже в том случае, если у нас не было произвольного доступа, но только двунаправленный доступ к связанному списку, например, состоит в использовании двух итераторов (один получает декремент, другой получает приращение и доступ к первому элементу в начало). – 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 
} 

Должен делать то, что вы хотите

+0

+1 для элегантности в форме; вам может потребоваться извлечь do_stuff в отдельную функцию, чтобы избежать дублирования кода, но в остальном это довольно красиво. –

+1

+1, для простоты –

+0

-1, для простоты – mario

5

В каждом цикле вы добавляете n*(-1)^(n+1), где n - это шаг, который вы сейчас делаете, начиная с 1, начиная с 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 

т.д.

Отсюда, это зависит от того, на каком языке вы хотели бы писать. Итерация от n = 0 туда, где вы остановки.

Редактировать Это плохой ответ. но весело = D

(я добавил, что последний бит, потому что, как только я сделал это изменить, кто-то downvoted меня =()

+0

+1 Это была моя непосредственная мысль и для ответа :) – NibblyPig

3

Вот реализация в JavaScript

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

Надеется, что это помогает.

+0

hehe nice skills :) – antpaw

+0

уменьшите свою зависимость от математики, выполнив '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

Я использовал функцию синуса:

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

Модификация решения падающей пули, которая будет обрабатывать регистр 0 без особых условий.

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

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

В этом цикле есть узор.Глядя на него на числовой прямой - он идет, как:

  • 0 шагов назад
  • 1 шаг вперед
  • 2 шага назад
  • 3 шага вперед
  • 4 шага назад

Вот одно решение - продолжайте увеличивать размер шага на каждой итерации цикла и каждый раз поворачивать направление (вперед/назад). Продолжайте добавлять к текущему значению.

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

Другое решение с использованием generators в JavaScript 1.7, который идентичен @ FallingBullet-х solution но более эстетично к моему глазу :)

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

В C. Значение N представляет общее количество значений в последовательности, которую вы хотите получить.

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

Только одно дополнение один вычитание и отрицание:

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

формирует внутреннюю петлю:

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

Для чего это стоит, вот моя собственная интерпретация проблемы.

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

я бы, вероятно, пойти с:

for (var i = 0; i <= max; i = (i <= 0) ? -i + 1 : -i) 
{ 
    f(i); 
} 
Смежные вопросы