Is there a way to calculate indexes generated by nested for loops?

I am currently thinking about how to store frequently used data. It is designed to be stored in an array and is currently being created as follows.

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);
                            }
                        }
                    }
                }
            }
        }
    }
}

Now my problem is to quickly access the calculated data using parameters a1-a7. The only approach I could think of was to repeat the same as during the iteration, until the parameters become the same as this.

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();
}

, , . - , . . Texas hold'em .

+4
3

index , a1... a7 - .

index formula

, .

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;
}

getIndex 1K .

+7

. , Map<String,Integer> indexMap = new HashMap<>(); -.

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));

, , , .

+1

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 ).

Note that it a1is multiplied by 100L, otherwise the result will be incorrect, since it does not correspond to the range of Integer.

0
source

Source: https://habr.com/ru/post/1666570/


All Articles