Java 查找所有可能的枚举组合
有没有一种有效的方法可以找到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"); } 我希望输出在这些多个枚举之间生成所有可能的组合,即
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));
}
}
}