Динамически создавать циклы для перебора списка List <String> - PullRequest
2 голосов
/ 08 октября 2011

У меня есть List из List<String>, которые я получаю при вызове метода внешнего API:

List<List<String>> outerList

Я должен создать уникальные комбинации клавиш, объединяя строки из каждого списка в одном и том жепорядок, в котором они находятся во внешнем списке.

Пример: если внешний список имеет 2 внутренних списка, скажем, list1: {"A", "B"} и list2: {"C", "D"}.Тогда возможными уникальными комбинациями будут AC, AD, BC и BD.

Но проблема в том, что размер outerList является динамическим, он может содержать любое количество внутренних списков.Если внутренние номера списка являются фиксированными, то я могу писать для циклов и создавать комбинации.

Я думаю о направлении использования отражений, рекурсии и т. Д., Но до сих пор не смог ее решить.

public static void main(String[] args) {

    List<List<String>> outerList = new ArrayList<List<String>>();
    List<String> list1 = new ArrayList<String>();
    list1.add("A");
    list1.add("B");
    List<String> list2 = new ArrayList<String>();

    list2.add("C");
    list2.add("D");
    outerList.add(list1);

    outerList.add(list2);

    for(String s1: list1) {
        for(String s2: list2) {
            System.out.println(s1+s2);
        }
    }
}

Здесь outerList имеет 2 внутренних списка, поэтому я создал 2 цикла for для итерации и объединения.Но в режиме реального времени externalList может иметь любое количество внутренних списков, как динамически циклически проходить через все внутренние циклы и объединять?

Ответы [ 2 ]

5 голосов
/ 08 октября 2011

У меня работает этот код:

public class Test
{  

    public static void generate(LinkedList<LinkedList<String>> outerList, String outPut) {
        LinkedList<String> list = outerList.get(0);

        for(String str : list) {
            LinkedList<LinkedList<String>> newOuter = new LinkedList<LinkedList<String>>(outerList);
            newOuter.remove(list);

            if(outerList.size() > 1) {
                generate(newOuter, outPut+str);
             } else {
               System.out.println(outPut+str);
             }
        }
    }

    public static void main(String[] args) 
    {
        LinkedList<LinkedList<String>> outerList = new LinkedList<LinkedList<String>>();

        LinkedList<String> list1 = new LinkedList<String>();
        LinkedList<String> list2 = new LinkedList<String>();

        list1.add("A");
        list1.add("B");

        list2.add("C");
        list2.add("D");

        outerList.add(list1);
        outerList.add(list2);

        Test.generate(outerList, "");
    }      
}

Выход:

AC
AD
До н.э.
BD

1 голос
/ 08 октября 2011

Пример данных с достаточным разбросом, чтобы продемонстрировать проблему:

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

    List<String> innerList1 = new ArrayList<String>();
    innerList1.add("A");
    innerList1.add("B");
    outerList.add(innerList1);

    List<String> innerList2 = new ArrayList<String>();
    innerList2.add("X");
    innerList2.add("Y");
    innerList2.add("Z");
    outerList.add(innerList2);

    List<String> innerList3 = new ArrayList<String>();
    innerList3.add("P");
    innerList3.add("Q");
    innerList3.add("R");
    outerList.add(innerList3);

Хранить массив счетчиков:

    int[] positions = new int[outerList.size()];

    boolean another = true;
    while (another) {
        for (int n = 0; n < outerList.size(); n++) {
            System.out.print(outerList.get(n).get(positions[n]));
        }
        System.out.println();

        another = false;
        for (int c = 0; c < outerList.size(); c++) {
            positions[c]++;
            if (positions[c] < outerList.get(c).size()) {
                another = true;
                break;
            }
            positions[c] = 0;
        }
    }

Каждый раз вокруг основного цикла я печатаю по одному элементу из каждоговнутренний списокЗатем я продвигаю счетчики, начиная с первого.Если это не выходит за пределы первого внутреннего списка, мы готовы снова напечатать.Но если это так, я устанавливаю этот счетчик на ноль и пытаюсь продвинуть второй, и так далее.Если все они переходят в ноль, пора выходить.

Это действительно похоже на подсчет, за исключением того, что каждый столбец имеет различную "базу" (вместо того, чтобы быть основанием десять или два или что-то еще).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...