开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜