以有效的方式获得所有可能的数组索引位置

时间:2016-03-21 16:09:25

标签: java arrays performance indexing

您好我想找到一种方法来查找任意大小和任意数量的维度大小数组中的所有可能的索引位置。例如:

int [][][] myArray = new int [2][3][2]

然后我会想要所有可能的数组索引位置,因此输出将类似于:

0,0,0
1,0,0
0,1,0
0,2,0

等等,基本上所有阵列的位置,以及比有很多嵌入式循环更有效的方法。

2 个答案:

答案 0 :(得分:1)

多维数组是语法糖,它们实际上位于单维存储器中:

所以,你可以试试这样的事情:

final int dim1 = 2;
final int dim2 = 3;
final int dim3 = 4;
final int[][][] myArray = new int[dim1][dim2][dim3];

for (long i = 0; i < ((long) dim1 * dim2 * dim3); i++) {
    long idx = i;
    final int i3 = (int) (idx % dim3);
    idx /= dim3;
    final int i2 = (int) (idx % dim2);
    idx /= dim2;
    final int i1 = (int) idx;
    System.out.println(i1 + "," + i2 + "," + i3);
}

注意:此代码使用的%/运算符非常慢,但如果您的维度为2的幂,则可以将其替换为&>>>哪个都可以更快地运行嵌套循环

另一种变体:

final int dim1 = 2;
final int dim2 = 3;
final int dim3 = 4;
final int[][][] myArray = new int[dim1][dim2][dim3];

int i1 = 0;
int i2 = 0;
int i3 = 0;
for (long i = 0; i < ((long) dim1 * dim2 * dim3); i++) {
    System.out.println(i1 + "," + i2 + "," + i3);
    i3++;
    if (i3 == dim3) {
        i3 = 0;
        i2++;
        if (i2 == dim2) {
            i2 = 0;
            i1++;
        }
    }
}

它可以更快地工作,但它具有分支内部循环,因此更好地对两个变体进行基准测试

答案 1 :(得分:0)

我赞成这样的做法。使用List这样的自定义实现的好处是,您可以表示所有可能的索引组合,而无需同时将它们全部存储在内存中。

public static void main(String[] args) {
    List<List<Integer>> indices = indices(2, 3);
    for (List<Integer> list : indices)
        System.out.println(list);
}

public static List<List<Integer>> indices(final int... dimensions) {
    int s = 1;
    for (int a : dimensions)
       s *= a;
    final int size = s;
    return new AbstractList<List<Integer>>() {
        @Override
        public int size() {
            return size;
        }
        @Override
        public List<Integer> get(int index) {
            if (index < 0 || index >= size)
                throw new IndexOutOfBoundsException();
            List<Integer> temp = new ArrayList<>();
            for (int d : dimensions) {
                temp.add(index % d);
                index /= d;
            }
            return Collections.unmodifiableList(temp);
        }
    };
}