2017-01-12 4 views
4

私は現在、頻繁にアクセスするデータをどのように格納するかについて考えています。これは配列に格納されることを意味し、現在次のように生成されています。ネストされたforループによって生成されたインデックスを計算する方法はありますか?

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

私の問題はすぐにA7のパラメータにA1を使用して計算されたデータにアクセスすることになりました。私は考えることができる唯一の方法は、速いだけの十分な量を考慮されていない、線形時間で実行されるパラメータが同じになるまで、この

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手は、いくつかのさらなるテストを行う。

+1

これはプログラミングに関する質問よりも多くの問題です –

+0

データはソートされているので、各a1、a2、...、a7の値をバイナリ検索してからインデックスを計算したいと思うかもしれません。 ex:index = a1の確立インデックス* a2の確立インデックス* a3の確立インデックス... – Minh

答えて

7

... a7は、この番号の数字です。ここ

formula of index

所与ループ変数から指数を計算する関数です。

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余分な静的メモリのが必要です。

+0

私が欲しかったものを正確にしますか? +1 – legendff

1

必要なインデックスへのマップに、パラメータを文字列キーとして格納することを検討できます。だから、どこかのクラスでMap<String,Integer> indexMap = new HashMap<>();と宣言できます。

generateDataメソッドでは、パラメータを1つの大きな文字列キーとして保存できます。

indexMap.put(Integer.toString(a1)+Integer.toString(a2)+ ... + 
    Integer.toString(a7),index); 

増分する前にインデックスを保存してください。これは、あなたがエラーを発見していないキーのエラーチェックを行う必要がありますが、その後

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

を行うことができるようになるが、これはあなたがはるかに速くしたいのインデックスを取得することができます。

0

妥当な時間内にa1 ... a7からインデックスを取得する効率的なアルゴがあるかどうかわからないので、を使用してa1..a7 -> compute valueを保持します。しかし、私は地図をキーとしてLongを使用し、これは、検索、鍵の生成と宇宙消費効率の良い(地図133784560個のエントリが含まれますをしなければならない

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

次の方法でそれを構築します)。それは整数の範囲に適合しないようa1100Lを掛けていることを

、そうでない場合は、結果は、不正確になります。

indexがループ変数 a1 Combinatorial number systemで数として扱うことができ、あなたの場合は
+1

これは7つの整数からインデックスを計算するだけのギガバイトのヒープメモリを必要とするため、ひどい解決策です。 – apangin

関連する問題