Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 查找所有可能的枚举组合_Java_Java 7_Java Collections Api - Fatal编程技术网

Java 查找所有可能的枚举组合

Java 查找所有可能的枚举组合,java,java-7,java-collections-api,Java,Java 7,Java Collections Api,有没有一种有效的方法可以找到Java中多个枚举之间的所有可能组合 考虑以下三个枚举- public enum EnumOne { One ("One"), OneMore ("OneMore"); } public enum EnumTwo { Two ("Two"), } public enum EnumThree { Three ("Three"), ThreeMore ("ThreeMore"); } 我希望输出在这些多个枚举之间生成所有可能的组合,即

有没有一种有效的方法可以找到Java中多个枚举之间的所有可能组合

考虑以下三个枚举-

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}
希望找到一种有效的处理方法


谢谢,像这样的怎么样

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

算法的复杂度是O(NxMxK…xZ)如果我错了,我不知道这是否是一种“有效的方法”。。。。我用它作为回溯解决方案

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ProductEnums {

    public enum EnumOne {
        One,
        OneMore;
    }

    public enum EnumTwo {
        Two,
    }

    public enum EnumThree {
        Three,
        ThreeMore;
    }

    public static void main(String[] args) {
        // pass each values in enums
        List a = product(EnumOne.values(),
                EnumTwo.values(), EnumThree.values());
        System.out.println(a);
    }

    public static List<List<Enum>> product(Enum[]... enums) {
        return product(new ArrayList<>(Arrays.asList(enums)));
    }

    public static List<List<Enum>> product(List<Enum[]> enums) {
        if (enums.isEmpty()) {
            //Trivial case of recursive function
            return new ArrayList<>();
        }
        //remove first element
        Enum[] myEnums = enums.remove(0);
        List<List<Enum>> out = new ArrayList<>();
        for (Enum e : myEnums) {
            //call recursive
            List<List<Enum>> list = product(enums);
            for (List<Enum> list_enum : list) {
                //for each list get from recursion adding element e
                list_enum.add(0, e);
                out.add(list_enum);
            }
            if(list.isEmpty()){
                List<Enum> list_enum = new ArrayList<>();
                list_enum.add(e);
                out.add(list_enum);
            }
        }
        enums.add(0, myEnums); //Backtraking
        return out;
    }
}
import java.util.ArrayList;
导入java.util.array;
导入java.util.List;
公共类产品枚举{
公共枚举枚举一{
一,,
再一次;
}
公共枚举枚举2{
二,,
}
公共枚举枚举三{
三,,
再有三个;
}
公共静态void main(字符串[]args){
//在枚举中传递每个值
列表a=产品(EnumOne.values(),
EnumTwo.values(),EnumTwo.values());
系统输出打印项次(a);
}
公共静态列表产品(枚举[]…枚举){
返回产品(新的ArrayList(Arrays.asList(enums));
}
公共静态列表产品(列表枚举){
if(enums.isEmpty()){
//递归函数的平凡情形
返回新的ArrayList();
}
//删除第一个元素
Enum[]myEnums=enums.remove(0);
List out=new ArrayList();
用于(枚举e:myEnums){
//调用递归
列表=产品(枚举);
用于(列表\u枚举:列表){
//对于每个列表,从添加元素e的递归中获取
列表_枚举添加(0,e);
out.add(list_enum);
}
if(list.isEmpty()){
List_enum=new ArrayList();
列表_枚举添加(e);
out.add(list_enum);
}
}
enums.add(0,myEnums);//回溯
返回;
}
}
结果

[一,二,三],[一,二,三],[一,二,三],[一,二,三]]


这是一个基于迭代器的解决方案。这样,如果它在许多枚举类型上运行并加载枚举常量,内存消耗就不会激增。因此,执行效率应该很高(而且实现避免了递归)


但是,当然,人们也可以用番石榴…

你在寻找比嵌套循环更好的东西吗?现在还不清楚你在问什么,尽可能少递归Eguava有一些用于功率集和排列的简洁函数…请看这里。如果使用
Arrays.asList(EnumOne.values())
等类似工具,则可用于枚举。有比将值放入字符串的O(K x M x N)更好的解决方案吗。“我不太确定这是否是我们所要求的。”@dhke,那就交给翻译了。无论哪种方式,如果需要,都可以更改输出。不需要是字符串[],可以是对象[]。当它得到一个组合时,它不需要打印(如果需要,它可以将它存储在某个地方)。在声明中不需要使用
ArrayList
List
就足够了。这也是多个位置的不安全代码。我也不确定这是否算是有效的,因为它将整个(可能是大的列表)存储在内存中。如前所述,它可以在线性空间中完成。@dhke I在声明中固定了列表。。。。。在这段代码中,内存使用效率很低,这可能是错误的improved@dhke在中使用了更好的算法,但他们也使用中间列表作为解决方案的一部分。我已在注释中链接了我的解决方案版本,该注释适用于线性空间,但仅适用于索引列表(枚举值为)当然,它需要回调。我真的很想看到一个基于迭代器的也返回迭代器的迭代器,但我认为这变得非常复杂。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ProductEnums {

    public enum EnumOne {
        One,
        OneMore;
    }

    public enum EnumTwo {
        Two,
    }

    public enum EnumThree {
        Three,
        ThreeMore;
    }

    public static void main(String[] args) {
        // pass each values in enums
        List a = product(EnumOne.values(),
                EnumTwo.values(), EnumThree.values());
        System.out.println(a);
    }

    public static List<List<Enum>> product(Enum[]... enums) {
        return product(new ArrayList<>(Arrays.asList(enums)));
    }

    public static List<List<Enum>> product(List<Enum[]> enums) {
        if (enums.isEmpty()) {
            //Trivial case of recursive function
            return new ArrayList<>();
        }
        //remove first element
        Enum[] myEnums = enums.remove(0);
        List<List<Enum>> out = new ArrayList<>();
        for (Enum e : myEnums) {
            //call recursive
            List<List<Enum>> list = product(enums);
            for (List<Enum> list_enum : list) {
                //for each list get from recursion adding element e
                list_enum.add(0, e);
                out.add(list_enum);
            }
            if(list.isEmpty()){
                List<Enum> list_enum = new ArrayList<>();
                list_enum.add(e);
                out.add(list_enum);
            }
        }
        enums.add(0, myEnums); //Backtraking
        return out;
    }
}
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;
                }
            }
        }
    }
}
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));
        }
    }
}