1

List<List<String>> 最初の次元で可能なすべての連結のリストを取得する必要があります

[ [1,2 ], [1] , [3,4] ]

与える必要があります:

[ 113, 114, 213, 214 ]

私はそれが可能であるはずのように、2つのループで試しています。

これは私が試したことです:

private static List<String> constructIndexes(List<List<String>> indexList){
    List<String> index = new ArrayList<String>();

    String v="";

    for (int i=0; i< indexList.size(); i++){
        List<String> l =  indexList.get(i);
        for (int j=0; j<l.size(); j++){
            if (index.size()>0){
                for (int k=0; k<index.size(); k++){
                    index.set(k, index.get(k)+l.get(j));
                    // System.out.println(">");
                }
            } else {
                index.add(l.get(j));
            }

        }
    }

    return index;
}

いくつかの初期化コード:

List<List<String>> indexList = new ArrayList<List<String>>();

    List<String> l = new ArrayList<String>();
    l.add("1");
    l.add("2");
    indexList.add(l);
    l = new ArrayList<String>();
    l.add("1");
    indexList.add(l);
    l = new ArrayList<String>();
    l.add("3");
    l.add("4");
    indexList.add(l);

    System.out.println( constructIndexes(indexList));
4

3 に答える 3

1

各要素のインデックスを追跡するいくつかのインデックス カウンターを保持し、伝統的な左への繰り上げを行います。たとえば、9 + 1 = 10 (1 を左に繰り上げ、0 を設定) を加算する場合と同じです。

private static List<String> constructIndexes(List<List<String>> indexList) {
    List<String> index = new ArrayList<String>();
    int n = indexList.size();
    int[] counter = new int[n];
    int[] max = new int[n];
    int combinations = 1;
    for (int i = 0; i < n; i++) {
        max[i] = indexList.get(i).size();
        combinations *= max[i];
    }
    int nMinus1 = n - 1;
    for (int j = combinations; j > 0; j--) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < n; i++) {
            builder.append(indexList.get(i).get(counter[i]));
        }
        index.add(builder.toString());

        counter[nMinus1]++;
        for (int i = nMinus1; i >= 0; i--) {
            // overflow check
            if (counter[i] == max[i]) {
                if (i > 0) {
                    // carry to the left
                    counter[i] = 0;
                    counter[i - 1]++;
                }
            }
        }
    }
    return index;

テスト

List<List<String>> test = Arrays.asList(Arrays.asList("1", "2"),
        Arrays.asList("1"), Arrays.asList("3", "4"));
System.out.println(constructIndexes(test));

出力

[113, 114, 213, 214]
于 2012-06-19T22:55:42.420 に答える
0

これはあなたのために働くでしょうか

 private <T> List<T> getNthCombination(List<List<T>> lists, int n) {

    List<T> nthCombination = new ArrayList<T>(lists.size());

    int nCarry = n;
    for (List<? extends T> list: lists) {
         int lSize = list.size();
         nthCombination.add(list.get(nCarry % lSize));
         nCarry /= lSize;
    }

    return nthCombination;
}

もちろん、これは基本的な組み合わせの問題であり、この種のものを処理するライブラリがあります。

于 2012-06-20T07:08:51.783 に答える
0

外側のリスト (リストのリスト) 内のリストの数は実行時までわからないため、事前にループの数を知ることはできません。このような状況では、再帰的なソリューションが必要です。

public static void combine(List<List<String>> data, int[] pos, int n, List<String> res) {
    if (n == pos.length) {
        StringBuilder b = new StringBuilder();
        for (int i = 0 ; i != pos.length ; i++) {
            b.append(data.get(i).get(pos[i]));
        }
        res.add(b.toString());
    } else {
        for (pos[n] = 0 ; pos[n] != data.get(n).size() ; pos[n]++) {
            combine(data, pos, n+1, res);
        }
    }
}

これを呼び出す方法は次のとおりです。

List<List<String>> indexList = new ArrayList<List<String>>();
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
List<String> b = new ArrayList<String>();
b.add("1");
List<String> c = new ArrayList<String>();
c.add("3");
c.add("4");
indexList.add(a);
indexList.add(b);
indexList.add(c);
List<String> res = new ArrayList<String>();
combine(indexList, new int[indexList.size()], 0, res);
for (String s : res) {
    System.out.println(s);
}
于 2012-06-19T22:21:49.957 に答える