我如何获得符号的所有组合(如何迭代此数组)?

时间:2019-03-07 07:30:22

标签: java arraylist

我有这个符号arraylist

    public ArrayList<ArrayList<Letter>> setLetters() {
    ArrayList<ArrayList<Letter>> letters = new ArrayList<>();
    ArrayList<Letter> letter = new ArrayList<>();

    letter.add(new Letter('r', 0, 0));
    letter.add(new Letter('r', 1, 6));
    letter.add(new Letter('r', 3, 9));
    letters.add(letter);

    letter = new ArrayList<>();
    letter.add(new Letter('e', 4, 1));
    letter.add(new Letter('e', 4, 3));
    letters.add(letter);

    letter = new ArrayList<>();
    letter.add(new Letter('s', 4, 6));
    letter.add(new Letter('s', 4, 7));
    letter.add(new Letter('s', 5, 1));
    letters.add(letter);

    letter = new ArrayList<>();
    letter.add(new Letter('o', 5, 4));
    letters.add(letter);

    letter = new ArrayList<>();
    letter.add(new Letter('r', 5, 5));
    letter.add(new Letter('r', 5, 9));
    letters.add(letter);

    letter = new ArrayList<>();
    letter.add(new Letter('s', 6, 2));
    letter.add(new Letter('s', 8, 2));
    letter.add(new Letter('s', 8, 3));
    letters.add(letter);

    letter = new ArrayList<>();
    letter.add(new Letter('e', 6, 5));
    letter.add(new Letter('e', 6, 7));
    letter.add(new Letter('e', 6, 8));
    letter.add(new Letter('e', 7, 3));
    letter.add(new Letter('e', 7, 8));
    letter.add(new Letter('e', 9, 2));
    letter.add(new Letter('e', 9, 3));
    letters.add(letter);

    letter = new ArrayList<>();
    letter.add(new Letter('s', 7, 1));
    letter.add(new Letter('s', 9, 4));
    letters.add(letter);

 return letters;
}

如何在ArrayList中像这样获得所有1512个符号组合

  

r {0,0} e {4,1} s {4,6} o {5,4} r {5,5} s {6,2} e {6,5} s {7,1 };   r {0,0} e {4,1} s {4,6} o {5,4} r {5,5} s {6,2} e {6,5} s {9,4}; ....

另外1510个组合

Idk如何迭代此数组> << / p>

4 个答案:

答案 0 :(得分:2)

计算排列的数量(在您的情况下为1510-将所有单个集合的大小相乘)。

然后对于每个迭代索引,您只需执行模运算就可以从每个集合中追加一个项目,然后除以相同的集合大小,然后再从集合中选择下一个项目。

类似这样的东西:

long permutations = 1;

for (int i = 0; i < letter.size(); i++)
{
    int setcount = letter[i].size();
    if (setcount == 0)
    {
       continue;
    }
    permutations *= setcount;
}

for (long p = 0; p < permutations; p++)
{
    long index = p;
    String s = "";

    for (int i = 0; i < letter.size(); i++)
    {
        if (letter[i].size() > 0)
        {
            ArrayList<Letter> innerIndex = index % letter[i].size();
            index /= letter[i].size();

            // append letter[i].get(innerIndex) to s, then append a semi-colon 
        }
    }

    System.out.println(s);
}

答案 1 :(得分:0)

这是一个递归算法:

public static void generateCombinations(
        List<List<Letter>> letters, Consumer<List<Letter>> handler) {
    List<List<Letter>> combinations = new ArrayList<>();
    addCombinations(letters, new ArrayList<>(), handler);
}

private static void addCombinations(List<List<Letter>> letters,
        List<Letter> current, Consumer<List<Letter>> handler) {
    int currentIndex = current.size();
    if (currentIndex >= letters.size()) {
        handler.accept(new ArrayList<>(current));
    } else {
        for (Letter letter: letters.get(currentIndex)) {
            current.add(letter);
            addCombinations(letters, current, handler);
            current.remove(currentIndex);
        }
    }
}

您将像这样使用它:

List<List<Letter>> letters = setLetters();
generateCombinations(letters, list -> System.out.println(list));

答案 2 :(得分:0)

您可以递归地执行此操作,而不必先评估组合的数量:

ArrayList<ArrayList<Letter>> combinations(ArrayList<ArrayList<Letter>> source, int step, ArrayList<ArrayList<Letter>> currentCombinations) {

    if( step == 0 ) {
        // init first pass because there are no current combinations.
        ArrayList<Letter> lettersAtStep = source.get(step);
        ArrayList<ArrayList<Letter>> nextCombinations = new ArrayList<>();

        for (Letter l : lettersAtStep) {
            ArrayList<Letter> firstLetter = new ArrayList<>();
            firstLetter.add(l);
            nextCombinations.add(firstLetter);
        }
        return combinations(source, step+1, nextCombinations);
    }
    else if( step == source.size() ) {
        // No more letters to add.
        return currentCombinations;
    }

    ArrayList<Letter> lettersAtStep = source.get(step);
    ArrayList<ArrayList<Letter>> nextCombinations = new ArrayList<>();

    for( ArrayList<Letter> comb : currentCombinations) {
        for (Letter l : lettersAtStep) {
            // Add each new Letter to each existing combination.
            ArrayList<Letter> item = new ArrayList(comb);
            item.add(l);
            nextCombinations.add(item);
        }
    }

    return combinations(source, step+1, nextCombinations);
}

然后,您将其命名为:

 combinations(setLetters(), 0, new ArrayList<>());

它将返回您在ArrayList中的所有组合。

答案 3 :(得分:0)

您也可以使用Iterator

public <T> Iterator<List<T>> combinations(final List<List<T>> lists) {
    return new Iterator<List<T>>() {
        // One index for each list.
        int[] index = new int[lists.size()];
        boolean justStarted = true;

        @Override
        public boolean hasNext() {
            // We've finished when all the indexes are back at zero.
            if (justStarted) {
                justStarted = false;
                return true;
            }
            // Any of them non-zero?
            for (int i : index) {
                if (i != 0) return true;
            }
            return false;
        }

        @Override
        public List<T> next() {
            List<T> next = new ArrayList<>(lists.size());
            // Make the current one.
            for (int i = 0; i < lists.size(); i++) {
                next.add(i, lists.get(i).get(index[i]));
            }
            // Take one step.
            for (int i = lists.size() - 1; i >= 0; i--) {
                // Step on one list.
                if (++index[i] < lists.get(i).size()) break;
                // List exhausted - reset it to zero.
                index[i] = 0;
            }
            return next;
        }
    };

}

class Letter {
    private final char c;
    private final int x;
    private final int y;

    public Letter(char c, int x, int y) {
        this.c = c;
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return c + "{" + x + "," + y + "}";
    }
}

public List<List<Letter>> setLetters() {
    List<List<Letter>> letters = new ArrayList<>();

    letters.add(Arrays.asList(
            new Letter('r', 0, 0),
            new Letter('r', 1, 6),
            new Letter('r', 3, 9)));

    letters.add(Arrays.asList(
            new Letter('e', 4, 1),
            new Letter('e', 4, 3)));

    letters.add(Arrays.asList(
            new Letter('s', 4, 6),
            new Letter('s', 4, 7),
            new Letter('s', 5, 1)));

    letters.add(Arrays.asList(
            new Letter('o', 5, 4)));

    letters.add(Arrays.asList(
            new Letter('r', 5, 5),
            new Letter('r', 5, 9)));

    letters.add(Arrays.asList(
            new Letter('s', 6, 2),
            new Letter('s', 8, 2),
            new Letter('s', 8, 3)));

    letters.add(Arrays.asList(
            new Letter('e', 6, 5),
            new Letter('e', 6, 7),
            new Letter('e', 6, 8),
            new Letter('e', 7, 3),
            new Letter('e', 7, 8),
            new Letter('e', 9, 2),
            new Letter('e', 9, 3)));

    letters.add(Arrays.asList(
            new Letter('s', 7, 1),
            new Letter('s', 9, 4)));

    return letters;
}

private void test() {
    List<List<Letter>> letters = setLetters();
    Iterator<List<Letter>> combinations = combinations(letters);
    int count = 0;
    while (combinations.hasNext()) {
        List<Letter> next = combinations.next();
        System.out.println(next);
        count += 1;
    }
    System.out.println(count);
}

注意:这可能有一个小问题,因为它认为存在1512个组合。