In other words, can I do something like
for() { for { for { } } }
Except N times? In other words, when the method creating the loops is called, it is given some parameter N, and the method would then create N of these loops nested one in another?
Of course, the idea is that there should be an "easy" or "the usual" way of doing it. I already have an idea for a very complicated one.
"Are nested for-loops always O(n^2)?" To your other question, the answer is no. They aren't always O(n^2) . You can easily create a situation where one of the loops affects the iterations of the other, yielding a different complexity.
The C language allows for up to 127 levels of nested blocks; like 640KB of RAM, that's all anyone should ever need.
A method in Java can be up to a maximum of 64KB. So, you can have as many nested loops as long as they are under the 64KB of memory.
for-each loop can be nested like normal for loop.
jjnguy is right; recursion lets you dynamically create variable-depth nesting. However, you don't get access to data from the outer layers without a little more work. The "in-line-nested" case:
for (int i = lo; i < hi; ++i) { for (int j = lo; j < hi; ++j) { for (int k = lo; k < hi; ++k) { // do something **using i, j, and k** } } }
keeps the variables i
, j
, and k
in scope for the innermost body to use.
Here's one quick hack to do that:
public class NestedFor { public static interface IAction { public void act(int[] indices); } private final int lo; private final int hi; private final IAction action; public NestedFor(int lo, int hi, IAction action) { this.lo = lo; this.hi = hi; this.action = action; } public void nFor (int depth) { n_for (0, new int[0], depth); } private void n_for (int level, int[] indices, int maxLevel) { if (level == maxLevel) { action.act(indices); } else { int newLevel = level + 1; int[] newIndices = new int[newLevel]; System.arraycopy(indices, 0, newIndices, 0, level); newIndices[level] = lo; while (newIndices[level] < hi) { n_for(newLevel, newIndices, maxLevel); ++newIndices[level]; } } } }
The IAction
interface stipulates the role of a controlled action which takes an array of indices as the argument to its act
method.
In this example, each instance of NestedFor
is configured by the constructor with the iteration limits and the action to be performed by the innermost level. The parameter of the nFor
method specifies how deeply to nest.
Here's a sample usage:
public static void main(String[] args) { for (int i = 0; i < 4; ++i) { final int depth = i; System.out.println("Depth " + depth); IAction testAction = new IAction() { public void act(int[] indices) { System.out.print("Hello from level " + depth + ":"); for (int i : indices) { System.out.print(" " + i); } System.out.println(); } }; NestedFor nf = new NestedFor(0, 3, testAction); nf.nFor(depth); } }
and the (partial) output from its execution:
Depth 0 Hello from level 0: Depth 1 Hello from level 1: 0 Hello from level 1: 1 Hello from level 1: 2 Depth 2 Hello from level 2: 0 0 Hello from level 2: 0 1 Hello from level 2: 0 2 Hello from level 2: 1 0 Hello from level 2: 1 1 Hello from level 2: 1 2 Hello from level 2: 2 0 Hello from level 2: 2 1 Hello from level 2: 2 2 Depth 3 Hello from level 3: 0 0 0 Hello from level 3: 0 0 1 Hello from level 3: 0 0 2 Hello from level 3: 0 1 0 ... Hello from level 3: 2 1 2 Hello from level 3: 2 2 0 Hello from level 3: 2 2 1 Hello from level 3: 2 2 2
It sounds like you may want to look into recursion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With