Java 有没有办法计算嵌套for循环生成的索引?

Java 有没有办法计算嵌套for循环生成的索引?,java,arrays,performance,for-loop,Java,Arrays,Performance,For Loop,我目前正在考虑如何存储频繁访问的数据。它将存储在一个数组中,并且当前以以下方式生成 public static void generateData() { int index = 0; for(int a1 = 0; a1 < 52; a1++) { for(int a2 = a1 + 1; a2 < 52; a2++) { for(int a3 = a2 + 1; a3 < 52; a3++) {

我目前正在考虑如何存储频繁访问的数据。它将存储在一个数组中,并且当前以以下方式生成

public static void generateData() {

    int index = 0;
    for(int a1 = 0; a1 < 52; a1++) {
        for(int a2 = a1 + 1; a2 < 52; a2++) {
            for(int a3 = a2 + 1; a3 < 52; a3++) {
                for(int a4 = a3 + 1; a4 < 52; a4++) {
                    for(int a5 = a4 + 1; a5 < 52; a5++) {
                        for(int a6 = a5 + 1; a6 < 52; a6++) {
                            for(int a7 = a6 + 1; a7 < 52; a7++) {
                                data[index++] = compute(a1,a2,a3,a4,a5,a6,a7);
                            }
                        }
                    }
                }
            }
        }
    }
}
公共静态void generateData(){
int指数=0;
对于(int a1=0;a1<52;a1++){
对于(int a2=a1+1;a2<52;a2++){
对于(INTA3=a2+1;a3<52;a3++){
对于(int a4=a3+1;a4<52;a4++){
对于(int a5=a4+1;a5<52;a5++){
对于(int a6=a5+1;a6<52;a6++){
对于(int a7=a6+1;a7<52;a7++){
数据[索引+]=计算(a1、a2、a3、a4、a5、a6、a7);
}
}
}
}
}
}
}
}
我现在的问题是使用a1到a7参数快速访问计算数据。我能想到的唯一方法是在迭代期间进行类似的迭代,直到参数相同,如下所示

public static int getIndex(int i1, int i2, int i3, int i4, int i5, int i6, int i7) {
    int index = 0;
    for(int a1 = 0; a1 < 52; a1++) {
        for(int a2 = a1 + 1; a2 < 52; a2++) {
            for(int a3 = a2 + 1; a3 < 52; a3++) {
                for(int a4 = a3 + 1; a4 < 52; a4++) {
                    for(int a5 = a4 + 1; a5 < 52; a5++) {
                        for(int a6 = a5 + 1; a6 < 52; a6++) {
                            for(int a7 = a6 + 1; a7 < 52; a7++) {

                                if(a1 == i1 && a2 == i2 && a3 == i3 && a4 == i4 && a5 == i5 && a6 == i6 && a7 == i7) {
                                    return index;
                                } else {
                                    index++;
                                }

                            }
                        }
                    }
                }
            }
        }
    }

    throw new IllegalArgumentException();
}
publicstaticintgetindex(inti1、inti2、inti3、inti4、inti5、inti6、inti7){
int指数=0;
对于(int a1=0;a1<52;a1++){
对于(int a2=a1+1;a2<52;a2++){
对于(INTA3=a2+1;a3<52;a3++){
对于(int a4=a3+1;a4<52;a4++){
对于(int a5=a4+1;a5<52;a5++){
对于(int a6=a5+1;a6<52;a6++){
对于(int a7=a6+1;a7<52;a7++){
如果(a1==i1&&a2==i2&&a3==i3&&a4==i4&&a5==i5&&a6==i6&&a7==i7){
收益指数;
}否则{
索引++;
}
}
}
}
}
}
}
}
抛出新的IllegalArgumentException();
}
然而,这种方法只在线性时间运行,考虑到数据量,速度不够快。正因为如此,我想知道是否有任何方法可以计算常数时间或对数时间的指数。
因为我的问题可能看起来很模糊。我将存储所有可能的结果<代码>德克萨斯HOLD'EM/COD>手工做进一步的测试。

< P>您可以考虑将参数作为一个字符串键存储在一个映射到您需要的索引中。因此可以声明
Map indexMap=newhashmap()在你班的某个地方

然后在generateData方法中,可以将参数存储为一个大字符串键

    indexMap.put(Integer.toString(a1)+Integer.toString(a2)+ ... +
    Integer.toString(a7),index);
只需确保在递增索引之前存储索引即可。这将允许您这样做

    return indexMap.get(Integer.toString(a1)+Integer.toString(a2)+ ... +
    Integer.toString(a7));

您应该对未找到的键错误进行错误检查,但这将允许您更快地检索所需的索引。

我将使用
HashMap
来保持
a1..a7->compute value
,因为我不确定是否有有效的算法从
a1检索索引。。。a7
在合理的时间内。但是我会使用
Long
作为映射键,并用下一种方法构造它

long key = (((((a1 * 100L + a2) * 100 + a3) * 100 + a4) * 100 + a5) * 100 + a6) * 100 + a7
或者作为一个函数

public static long getKey(int ... array) {
    if (array.length != 7) {
        throw new IllegalArgumentException();
    }
    long value = 0;
    for (int item : array) {
        value = value * 100 + item;
    }
    return value;
}
这将使搜索、密钥生成和空间消耗更加高效(地图将包含133784560个条目)


请注意,
a1
乘以
100L
,否则结果将不正确,因为它不适合整数范围。

在您的情况下,
索引可以被视为中的一个数字,其中循环变量
a1
a7
是该数字的数字

下面是一个从给定循环变量计算索引的函数

public static int getIndex(int a1, int a2, int a3, int a4, int a5, int a6, int a7) {
    return 133784559 - (C7[a1] + C6[a2] + C5[a3] + C4[a4] + C3[a5] + C2[a6] + (51 - a7));
}

static final int[] C2 = Ck(2), C3 = Ck(3), C4 = Ck(4), C5 = Ck(5), C6 = Ck(6), C7 = Ck(7);

// Creates a cache of C(51-i, k) for 0 <= i < 52
static int[] Ck(int k) {
    int[] result = new int[52];
    for (int i = 0; i < 52; i++) {
        result[i] = (int) C(51 - i, k);
    }
    return result;
}

// Computes binomial coefficient C(n, k)
static long C(int n, int k) {
    long C = 1;
    for (int i = 0; i < k; i++) {
        C = C * (n - i) / (i + 1);
    }
    return C;
}
publicstaticintgetindex(inta1、inta2、inta3、inta4、inta5、inta6、inta7){
返回133784559-(C7[a1]+C6[a2]+C5[a3]+C4[a4]+C3[a5]+C2[a6]+(51-a7));
}
静态最终int[]C2=Ck(2),C3=Ck(3),C4=Ck(4),C5=Ck(5),C6=Ck(6),C7=Ck(7);

//为0创建一个C(51-i,k)缓存这更像是一个数学问题而不是一个编程问题,因为数据是经过排序的,所以您可能希望对每个a1、a2、…、a7值使用二进制搜索,然后计算索引。例如:index=a1的已建立索引*a2的已建立索引*a3的已建立索引…这是一个糟糕的解决方案,因为仅从7个整数计算索引就需要千兆字节的堆内存。这正是我想要的+1.