Java 树结构算法
我的程序有问题。例如,我有5个字段。这些字段的值为Java 树结构算法,java,combinations,permutation,Java,Combinations,Permutation,我的程序有问题。例如,我有5个字段。这些字段的值为true或false错误字段可以删除。所以我想找到这些字段的所有可能组合 我的想法是:例如,我有一个包含这些字段的XML 字段1,正确 第二场,没错 字段3,错误 字段4,错误 字段5,错误 结果应该是: {Field1, Field2, Field3, Field4, Field5} {Field1, Field2, , Field4, Field5} {Field1, Field2, , , Field
true
或false
<代码>错误字段可以删除。所以我想找到这些字段的所有可能组合
我的想法是:例如,我有一个包含这些字段的XML
- 字段1,正确
- 第二场,没错
- 字段3,错误
- 字段4,错误
- 字段5,错误
{Field1, Field2, Field3, Field4, Field5}
{Field1, Field2, , Field4, Field5}
{Field1, Field2, , , Field5}
{Field1, Field2, , , }
{Field1, Field2, Field3, , Field5}
{Field1, Field2, Field3, , }
{Field1, Field2, Field3, Field4, }
{Field1, Field2, , Field4, }
8种组合
我的想法是,它可以用树结构来解决。我将检查当前字段是否为“真”或“假”。如果“true”,那么我将向前移动一个字段。如果字段为“false”,我将复制XML,并在列表中添加一次当前“false”字段和一次不添加该字段。
比如这里的图片。
}
如何更改此部分“prefixWithField.add(?)
您可以使用字符串处理它,这是因为列表也是字符串类型。
但我和List一起工作
iterateRight()仅使用控制台打印。
IETerrateLeft()删除当前字段并使用控制台打印。
存在多个问题:
- 如果当前树节点有两个子节点,则必须同时进入这两个子节点,而不仅仅是左侧的子节点
- 最后,您返回了
(engl.sammlung
),但从未添加任何元素(至少不在显示的代码中)collection
- 结合递归的
循环似乎有些奇怪。但是我不能在不看while
和iterateLeft
的情况下谈论这一点iterateRight
Fieldmatrix
类被String
取代
public static List<List<String>> combine(List<String> fields) {
return combine(fields, 0, new ArrayList<>());
}
public static List<List<String>> combine(List<String> fields,
int start, List<String> prefix) {
List<List<String>> combinations = new ArrayList<>();
if (start >= fields.size()) {
combinations.add(prefix);
return combinations;
}
String field = fields.get(start);
if (field.contains("false")) {
combinations.addAll(combine(fields, start + 1, prefix));
}
List<String> prefixWithField = new ArrayList<>(prefix);
prefixWithField.add(field);
combinations.addAll(combine(fields, start + 1, prefixWithField));
return combinations;
}
公共静态列表组合(列表字段){
返回组合(字段,0,新ArrayList());
}
公共静态列表组合(列表字段,
int开始,列表前缀){
列表组合=新的ArrayList();
如果(开始>=fields.size()){
组合。添加(前缀);
收益组合;
}
字符串字段=字段。获取(开始);
if(field.contains(“false”)){
addAll(合并(字段,开始+1,前缀));
}
List prefixWithField=新的ArrayList(前缀);
前缀WithField.add(字段);
combinations.addAll(合并(字段,开始+1,前缀WithField));
收益组合;
}
这种实现不是很有效。许多中间结果被一次又一次地复制
例子
List fields=new ArrayList();
字段。添加(“1:true”);
字段。添加(“2:true”);
字段。添加(“3:false”);
字段。添加(“4:false”);
字段。添加(“5:false”);
合并(字段).forEach(c->System.out.println(c));
印刷品
[1:true, 2:true]
[1:true, 2:true, 5:false]
[1:true, 2:true, 4:false]
[1:true, 2:true, 4:false, 5:false]
[1:true, 2:true, 3:false]
[1:true, 2:true, 3:false, 5:false]
[1:true, 2:true, 3:false, 4:false]
[1:true, 2:true, 3:false, 4:false, 5:false]
[1:正确,2:正确]
[1:正确,2:正确,5:错误]
[1:正确,2:正确,4:错误]
[1:正确,2:正确,4:错误,5:错误]
[1:正确,2:正确,3:错误]
[1:正确,2:正确,3:错误,5:错误]
[1:正确,2:正确,3:错误,4:错误]
[1:true,2:true,3:false,4:false,5:false]
你说“我不能实现复制功能”是什么意思?你为什么不简单地数一数呢?从一个配置开始,它本质上是一个bool,用于初始化为true的每个字段,然后在其上应用一个运算符,搜索最右的可删除元素,翻转其值,并且每当它从false翻转为true时,它都会继续向左执行该操作。正如人们会对二进制数进行计数一样,只有0和1被颠倒,而忽略不可删除的“数字”。也就是说,您的问题有点不清楚-您是在问一种算法,如何查找所有组合,还是如何复制XML?另外,我真的建议用英语命名所有内容。这将有助于向我们展示
iterateLeft
和iterateRight
的实现。
public static List<List<String>> combine(List<String> fields) {
return combine(fields, 0, new ArrayList<>());
}
public static List<List<String>> combine(List<String> fields,
int start, List<String> prefix) {
List<List<String>> combinations = new ArrayList<>();
if (start >= fields.size()) {
combinations.add(prefix);
return combinations;
}
String field = fields.get(start);
if (field.contains("false")) {
combinations.addAll(combine(fields, start + 1, prefix));
}
List<String> prefixWithField = new ArrayList<>(prefix);
prefixWithField.add(field);
combinations.addAll(combine(fields, start + 1, prefixWithField));
return combinations;
}
List<String> fields = new ArrayList<>();
fields.add("1:true");
fields.add("2:true");
fields.add("3:false");
fields.add("4:false");
fields.add("5:false");
combine(fields).forEach(c -> System.out.println(c));
[1:true, 2:true]
[1:true, 2:true, 5:false]
[1:true, 2:true, 4:false]
[1:true, 2:true, 4:false, 5:false]
[1:true, 2:true, 3:false]
[1:true, 2:true, 3:false, 5:false]
[1:true, 2:true, 3:false, 4:false]
[1:true, 2:true, 3:false, 4:false, 5:false]