Generalizing a for-loop in Java
I don't really know how to describe my issue, so I'll just show a code example:
int[][][] mat;
int n;
int specificValue;
for (int i = 0; i < n; i++) {
if(mat[i][n-i][3] != specificValue) {
doStuff();
}
}
I'm looking up Integer values in a 3d-array. For each field I have to use one of these:
- a counter running from zero to n
- a counter running from n to zero
- a fixed value
So i've tried to build a Method that would save me from writing this for loop about 20 times, but i failed, so that's where i need help. My idea was something like this:
search(Loop.UP, Loop.DOWN, Loop.FIXED);
where "Loop" would be an enum representing one of my possibilities, but I don't know how to implement it or if this is even possible in Java without hardcoding every possible combination.
Hope you can help :)
OK, more specific... with my setup i'm drawing a vector through this 3d-array, a diagonal to be specific and i want to know what values are on this vector and only on this vector.
And because there is more than one possibility to draw such a vector, i'd like to have a more general method to get to the values. My search could just be as simple as
search(Loop.UP, Loop.FIXED, Loop.FIXED); // 开发者_运维知识库one plane
which would be a simple for-loop with one counter, but also
search(Loop.DOWN, Loop.UP, Loop.UP); // through all three planes
Path pathX = new Path.Up();
Path pathY = new Path.Down(n);
Path pathZ = new Path.Fixed(3);
for (int i = 0; i < n; i++) {
if(mat[pathX.pos(i)][pathY.pos(i)][pathZ.pos(i)] != specificValue) {
doStuff();
}
}
where
public interface Path {
public int pos(int i);
public static class Up implements Path {
@Override public int pos(int i) { return i; }
}
public static class Down implements Path {
private int n;
public Down(int n) { this.n = n; }
@Override public int pos(int i) { return n - i - 1; }
}
public static class Fixed implements Path {
private int v;
public Down(int v) { this.v = v; }
@Override public int pos(int i) { return v; }
}
I didn't use an Enum because Down
depends on n
and Fixed
on some value.
You could use a list of indices. In Python, it could look something like this:
LOOP_UP = 20
LOOP_DOWN = LOOP_UP + 20
LOOP_FIXED = LOOP_DOWN + 20
def indexesOfLoopType(loopType, val):
if loopType == LOOP_UP:
return range(val)
if loopType == LOOP_DOWN:
return range(val, 0)
return [val] * val # make a list [val, val, val... ] of length val
def search(loopFirstIndex, loopSecondIndex, loopThirdIndex):
# use indexesOfLoopType() to get lists of indexes
# use those lists to iterate over mat
The best I can think of at the moment is this:
static final int UP = -2, DOWN = -1;
static void loop1(int[][][] A, int t1, int t2, int t3) {
switch (t1) {
case UP:
for (int i = 0; i < A.length; i++)
loop2(A[i], t2, t3);
break;
case DOWN:
for (int i = A.length - 1; i >= 0; i--)
loop2(A[i], t2, t3);
break;
default:
loop2(A[t1], t2, t3);
}
}
static void loop2(int[][] A, int t2, int t3) {
switch (t2) {
case UP:
for (int i = 0; i < A.length; i++)
loop3(A[i], t3);
break;
case DOWN:
for (int i = A.length - 1; i >= 0; i--)
loop3(A[i], t3);
break;
default:
loop3(A[t2], t3);
}
}
static void loop3(int[] A, int t3) {
switch (t3) {
case UP:
for (int i = 0; i < A.length; i++) {
// Do something with A[i] here, such as...
System.out.println(A[i]);
}
break;
case DOWN:
for (int i = A.length - 1; i >= 0; i--) {
// Do something with A[i] here, such as...
System.out.println(A[i]);
}
break;
default:
// Do something with A[t3], such as...
System.out.println(A[t3]);
}
}
FIXED
is the only option which requires an index, and is thus encoded as an index. UP
and DOWN
are not indices, so they are encoded using negative numbers. Usage would go something like
public static void main(String[] args) {
int[][][] m = { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } };
loop1(m, DOWN, 1, UP);
}
With my System.out.println
example, the output would be
7
8
3
4
精彩评论