我是Java和Stack Overflow的新手,我对排列有疑问。
方法:我使用ArrayList
内的对象生成ArrayList
。每个ArrayList
的大小从1
(最小可能为1)到infinite
,并包含具有唯一名称属性的自定义生成对象。
问题现在我的问题是如何从第一个ArrayList
到最后一个ArrayList
获取所有可能的对象组合的排列(我想我们可以说那是我的外ArrayList
(y轴)中的x轴?
示例: 我试着画一个简单的例子:
ArrayList
:1.1 | 1.2 | 1.3 ArrayList
:2.1 ArrayList
:3.1 | 3.2 此处ArrayLists
位于ArrayList
外部(因为对象可能ArrayLists
的数量未知)。第二个数字是显示不同的对象。让我们说“让每一种可能的组合从上到下”。
结果: 我想得到一个看起来像这样的结果:
编辑:这里的分隔符“|”代表例如ArrayList中的一个槽。组合不应该在控制台中写入,因为我需要单独访问排列的每个对象。
最好的情况是,如果我可以让每个组合接着另一个组合,因为我想检查每个组合的几个条件,并且只在另一个ArrayList
或.txt文件中安全某些组合。
到目前为止我得到了什么:
我找到了一个代码段,它在ArrayLists
内使用Strings
置换ArrayList
,并返回带有ArrayList
合并的Strings
个。{/ p>
public static ArrayList<String> combineAllCases(ArrayList<ArrayList<String>> totalList)
{
ArrayList<String> result = new ArrayList<String>(totalList.get(0));
for(int index = 1; index < totalList.size() ; index++)
{
result = (ArrayList<String>) combineTwoLists(result, totalList.get(index));
}
return result;
}
和
private static ArrayList<String> combineTwoLists(ArrayList<String> list1, ArrayList<String> list2)
{
ArrayList<String> result = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
for(String s1 : list1)
{
for(String s2: list2)
{
sb.setLength(0);
sb.append(s1).append("#").append(s2);
result.add(sb.toString());
}
}
return result;
}
想法:
使用此方法,我可以使用String
拆分来获取每个组合的每个对象名称,并可以搜索此名称旧ArrayLists
以获取对象。
问题:
此方法仅适用于ArrayLists
内的少量ArrayList
(例如,如上例所示)。如果有例如外部ArrayLists
中大小为7的ArrayList
,我得到"MemoryOutOfSpace"
错误。
如上所述,最好的情况是在组合后获得组合并单独决定是否要保留组合(我想我会将每个组合保存在.txt文件中,因为它可能是,我想要的保持每一个组合 - &gt;绕过"MemoryOutOfSpace"
- 错误的问题。
简短摘要:
内部 - ArrayLists
包含对象(大小从1到未知大小)。
外 - ArrayList
内部 - ArrayLists
(未知大小)。
通缉输出:从上到下的每个物体组合。
提前致谢。
答案 0 :(得分:0)
//编辑:我理解错误的问题。这不是一个正确的解决方案。
据我了解你的问题,你只需要遍历所有三个列表,获取所有元素并将它们加在一起。
这是一个简单的示例,其中包含3个String类型列表,其中包含您的示例:
List<String> l1 = new ArrayList<String>();
l1.add("1.1");
l1.add("1.2");
l1.add("1.3");
List<String> l2 = new ArrayList<String>();
l2.add("2.1");
List<String> l3 = new ArrayList<String>();
l3.add("3.1");
l3.add("3.2");
for (String s1 : l1)
{
for (String s2 : l2)
{
for (String s3 : l3)
{
System.out.println(s1 + " | " + s2 + " | " + s3);
}
}
}
打印
1.1 | 2.1 | 3.1
1.1 | 2.1 | 3.2
1.2 | 2.1 | 3.1
1.2 | 2.1 | 3.2
1.3 | 2.1 | 3.1
1.3 | 2.1 | 3.2
它做的很简单: 首先,我们使用您想要创建排列的值填充我们的三个数组。
然后我们真的可以读取代码:
For every String s1 in the list l1 we take every String s2 in l2. For those combinations we take every string s3 in l3. Then we print out the combination
所以它内部的作用是:
s1 | s2 | s3
1.1 | |
1.1 | 2.1 |
1.1 | 2.1 | 3.1 -> print
1.1 | 2.1 | 3.2 -> print
1.2 | |
1.2 | 2.1 | 3.1 -> print
1.2 | 2.1 | 3.2 -> print
1.3 | |
1.3 | 2.1 | 3.1 -> print
1.3 | 2.1 | 3.2 -> print
答案 1 :(得分:0)
我认为你问题的关键词是笛卡儿积,而不是排列。你可以尝试这样的事情:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.stream.Stream;
class Test{
public static void main(String[] args){
List<List<String>> totalList = new ArrayList<>();
totalList.add(Arrays.asList("1.1","1.2","1.3"));
totalList.add(Arrays.asList("2.1"));
totalList.add(Arrays.asList("3.1","3.2"));
Supplier<Stream<String>>[] sup = new Supplier[totalList.size()];
for(int i = 0; i<totalList.size();i++){
final int j = i;
sup[i]= () -> totalList.get(j).stream();
}
Stream<String> result = cartesian((a, b) -> a+"|"+b, sup);
result.forEach(System.out::println);
}
private static <T> Stream<T> cartesian(BinaryOperator<T> aggregator, Supplier<Stream<T>>... streams) {
return Arrays.stream(streams)
.reduce((s1, s2) ->
() -> s1.get().flatMap(t1 -> s2.get().map(t2 -> aggregator.apply(t1, t2))))
.orElse(Stream::empty).get();
}
}
有关更多信息,请参阅此其他SO问题: Cartesian product of streams in Java 8 as stream (using streams only)
答案 2 :(得分:0)
我认为你必须递归地做。也许可以在Java 8中使用流,但我还不熟悉它们。 所以这是使用递归的样子:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class ArrayLists {
ArrayList<List<String>> outer = new ArrayList(5);
List<String> helper = new ArrayList<String>();
public static void main(String[] args) {
ArrayLists arrayLists = new ArrayLists();
arrayLists.displayPermutations();
}
private void displayPermutations() {
List<String> l1 = new ArrayList<String>();
l1.add("1.1");
l1.add("1.2");
l1.add("1.3");
List<String> l2 = new ArrayList<String>();
l2.add("2.1");
l2.add("2.2");
List<String> l3 = new ArrayList<String>();
l3.add("3.1");
l3.add("3.2");
l3.add("3.3");
outer.add(l1);
outer.add(l2);
outer.add(l3);
initHelper();
recursion(l1);
}
private void initHelper() {
for(int i = 0; i < outer.size(); i++) {
helper.add(i, outer.get(i).get(0));
}
}
void recursion(List<String> listToIncrement) {
int helperIndex = outer.indexOf(listToIncrement);
for(int i = 0; i < listToIncrement.size(); i++) {
helper.set(helperIndex, listToIncrement.get(i));
if(helperIndex < outer.size() - 1) {
recursion(outer.get(helperIndex + 1));
}
else{
System.out.println(helper);
}
}
}
}
当然,你可以摆脱initHelper方法,它不是最干净的代码......