Make nested loop algorithm dynamic

I have an algorithm that looks something like this:

for m = 1 to 2
  initialize (work_item (m))
  for l = 1 to 2
    initialize (work_item (l))
    for k = 1 to 2
      initialize (work_item (k))
      for j = 1 to 2
        initialize (work_item (j))
        for i = 1 to 2
          initialize (work_item (i))
          doSomething (work_item (i))
        next
        doSomething (work_item (j))
      next
      doSomething (work_item (k))
    next
    doSomething (work_item (l))
  next
  doSomething (work_item (m))
next

How can I write it iteratively, making it dynamic so that I am not limited to a fixed number of for (i, j, k, l, m) loops (i.e. I can do (i) or (i, j) or (i , j, k) or (i, j, k, l) etc ...)?

( . , , .)

+6
9

, , . :.

var stack = new Stack();
stack.Push(InitialThingy);
while(stack.Count != 0)
{
    var currentItem = stack.Pop();
    //Do things to current item and add things to stack as we go.
}
+9
private sub doStuff(depth as integer)
    for i as integer = 1 to 2
        initialize(work_item(i))
        if depth > 1 then doStuff(depth - 1)
        doSomething(work_item(i))
    next
end sub

, , , , . , , .

+6
+3

[0]... [n] 1. do

int j, k;
for(j = n - 1; j >= 0; j--){
  initialize(i[j]);
}

while (true) {
  j = 0;
  while (i[j] == 2) {
    doSomething(i[j]);
    j++;
  }
  if (j < n) {
    doSomething(i[j]);
  } else {
    break;
  }
  for (j = 0; j < n; j++) {
     if (i[j] == 1) {
       i[j] = 2;
       break;
     }
     else {
       i[j] = 1;
     }
  }
  if (j == n) break;
  for (k = j; k >= 0; k--) {
    initialize(i[k]);
  }
}

, , , , . , , .

, [j] .

.

, , , , ( ). , . ,

for i = 1 to 2
   do beginning stuff with i
   do inner loop
   do ending stuff with i
next

, . , .

 i j k l
 1 1 1 1
 1 1 1 2
 1 1 2 1

. , , i -> i[3], j -> i[2], k -> i[1] l -> [0],

j = 0
while i[j] == 2
  i[j] = 1
  j++
if j == maxindex
  break out, we're done with all the loops
else
  i[j] = 2

, . , , . ,

j = 0
while i[j] == 2
  do ending stuff with i[j]
  i[j] = 1
  j++
if j == maxindex
  break out, we're done with all the loops
else
  do ending stuff with i[j]
  i[j] = 2

. , , .

  • (, , 1
  • inital increment , .

(, , )

, .

for j = maxindex - 1 downto 0
  do beginning stuff with i[j]
while true
  j = 0
  while i[j] == 2
    do ending stuff with i[j]
    i[j] = 1
    j++
  if j == maxindex
    break out, we're done with all the loops
  else
    do ending stuff with i[j]
    i[j] = 2

, , , .

for j = maxindex - 1 downto 0
  do beginning stuff with i[j]
while true
  j = 0
  while i[j] == 2
    do ending stuff with i[j]
    i[j] = 1
    j++
  if j == maxindex
    break out, we're done with all the loops
  else
    do ending stuff with i[j]
    i[j] = 2
  for k = j downto 0
    do beginning stuff with i[k]

( ..) . . , , , . De gustibus non dissandum est.

+2

deinst, 15 rep... , , deinst - . deinst , roygbiv . ( , deinst's.)

+2

depth, depth - . ,

function doEverything(depth) {
  if (depth == 0) return;

  var i; // a new local variable on each call
  for i = 1 to 2 {
    initialize(work_item(i));
    doEverything(depth-1);
    doSomething(work_item(i));
  }
}

i,j,k,... 1 2, .

, 2^depth .

+1
void doStuff(int depth)
{
    int i[depth];
    int sp = depth - 1;
    i[sp] = 0;

    while (1)
    {
        if (++i[sp] <= 2)              // "next".  This is why we init to 0.
        {                              // At this point, i[sp] is 1 or 2.
            // init item i[sp];

            if (sp)                    // If there space to nest another loop
            {
                i[--sp] = 0;           // Push a 0
                continue;              // Start iterating with the new 0 as TOS
            }
        } 
        else if (++sp >= depth)        // Here, i[sp] is 3.  Leave the inner loop
            break;                     // and exit if stack now empty

        // use item i[sp];
    }
}

, . , .

+1

, i, j, k,...

, , :

foreach (var seq in myCollection)
{
  initialize(seq[0]);
  initialize(seq[1]);
  initialize(seq[2]);
  ...
  doSomething(...);
}

, Eric Lippert LINQ:

static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
{ 
  IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() }; 
  return sequences.Aggregate( 
    emptyProduct, 
    (accumulator, sequence) =>  
      from accseq in accumulator  
      from item in sequence  
      select accseq.Concat(new[] {item}));                
}

{{1,2}, {1,2},... {1,2}} , {1,2} .

0

n . (Python):

a = ('ab', 'AB', '12')

def permutate(a, s='', nLevel=0):
    aResult = []
    if nLevel < len(a):
        for n in range(0, len(a[nLevel])):
            aResult += permutate(a, s + a[nLevel][n], nLevel + 1)
    else:
       aResult = [s]

    return aResult

print(permutate(a))

:

['aA1', 'aA2', 'aB1', 'aB2', 'bA1', 'bA2', 'bB1', 'bB2']
0

All Articles