7

Javaで複数の列挙型の間で可能なすべての組み合わせを見つける効率的な方法はありますか?

次の 3 つの列挙型を検討してください -

public enum EnumOne {
   One ("One"),
   OneMore ("OneMore");
}

public enum EnumTwo {
   Two ("Two"),
}

public enum EnumThree {
   Three ("Three"),
   ThreeMore ("ThreeMore");
}

これらの複数の列挙型の間で可能なすべての組み合わせを生成する出力が必要です。

{EnumOne.One, EnumTwo.Two, EnumThree.Three},
{EnumOne.One, EnumTwo.Two, EnumThree.ThreeMore},
{EnumOne.OneMore, EnumTwo.Two, EnumThree.Three},
{EnumOne.OneMore, EnumTwo.Two, EnumThree.ThreeMore}

効果的な対処法が見つかれば幸いです。

ありがとう

4

3 に答える 3

0

これはイテレータベースのソリューションです。このように、列挙型定数の負荷を伴う多くの列挙型で動作する場合、メモリ消費は爆発しません。したがって、実行効率は問題ないはずです (さらに、実装によって再帰が回避されます)。

import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

public class EnumCombination implements Iterable<Enum<?>[]> {

    private final Enum<?>[][] enumConstants;
    private final int[] limits;
    private final boolean emptyCombination;

    public EnumCombination(final List<Class<? extends Enum<?>>> enums) {
        this.limits = new int[enums.size()];
        this.enumConstants = new Enum<?>[enums.size()][];

        boolean empty = enums.isEmpty();
        for (int i = 0; i < enums.size(); i++) {
            final Enum<?>[] enumElements = enums.get(i).getEnumConstants();
            enumConstants[i] = enumElements;
            limits[i] = enumElements.length - 1;
            empty |= enumElements.length == 0;
        }
        this.emptyCombination = empty;
    }

    @Override
    public Iterator<Enum<?>[]> iterator() {
        return new EnumCombinationIterator();
    }

    private class EnumCombinationIterator implements Iterator<Enum<?>[]> {
        private final int[] cursors = new int[limits.length];
        private boolean exhausted = emptyCombination;

        @Override
        public boolean hasNext() {
            return !exhausted;
        }

        @Override
        public Enum<?>[] next() {
            if (exhausted)
                throw new NoSuchElementException();

            final Enum<?>[] result = new Enum<?>[cursors.length];
            for (int i = 0; i < cursors.length; i++) {
                result[i] = enumConstants[i][cursors[i]];
            }
            moveCursors();

            return result;
        }

        private void moveCursors() {
            for (int i = cursors.length - 1; i >= 0; i--) {
                cursors[i] = cursors[i] == limits[i] ? 0 : cursors[i] + 1;
                if (cursors[i] != 0) {
                    break;
                } else if (i == 0) {
                    exhausted = true;
                }
            }
        }
    }
}

EnumCombination次のように使用できます。

import java.util.*;

public class Main {

    public enum EnumOne {
        One,
        OneMore
    }

    public enum EnumTwo {
        Two
    }

    public enum EnumThree {
        Three,
        ThreeMore
    }

    public static void main(String... args) {
        EnumCombination enumCombination = new EnumCombination(
                Arrays.asList(EnumOne.class, EnumTwo.class, EnumThree.class));

        for (final Enum<?>[] ec : enumCombination) {
            System.out.println(Arrays.toString(ec));
        }
    }
}

しかし、もちろん、グアバも使用できますcartesianProduct()…</p>

于 2016-05-23T12:57:19.980 に答える
-1

このようなものはどうですか。

void printAll(List<Class> enums, int i, String[] msg) {
    if (!enums.get(i).isEnum()) {
        throw new IllegalStateException();
    }
    Object[] enumsConstants = enums.get(i).getEnumConstants();
    if (i == 0) {
        //first iteration
        for (Object o : enumsConstants) {
            if (enums.size() == 1) {
                System.out.println("{ " + o.toString() + " }");
            } else {
                msg = new String[enums.size()];
                msg[0] = "{ " + o.toString();
                printAll(enums, i + 1, msg);
            }
        }
    } else if (i == enums.size() - 1) {
        //on the last iteration
        for (Object o : enumsConstants) {
            msg[i] = ", " + o.toString() + " }";
            System.out.println(Arrays.toString(msg));
        }
    } else {
        //middle iteration
        for (Object o : enumsConstants) {
            msg[i] = ", " + o.toString();
            printAll(enums, i + 1, msg);
        }
    }
}

このように使用します

printAll(allMyEnumClassesList, 0, null);
于 2015-05-01T20:10:32.537 に答える