如何为数组中的项目创建所有组合?

How to create all combinations for items in an Array?

我确实在上面看到了 this and this post,但它不在 Java 或 Kotlin 中,所以它对我没有帮助。现在,问题来了,我希望能够为一个数组创建所有可能的组合。例如,我有这个数组:

[1,2,3,4]

然后所有可能的组合给我们这个:

[1,2,3,4]
[1,2,4,3]
[1,3,2,4]
[1,3,4,2]
[1,4,2,3]
[1,4,3,2]

[2,1,4,3]
[2,1,3,4]
[2,3,1,4]
[2,3,4,1]
[2,4,3,1]
[2,4,1,3]

[3,1,2,4]
[3,1,4,2]
[3,2,4,1]
[3,2,1,4]
[3,4,1,2]
[3,4,2,1]

[4,1,2,3]
[4,1,3,2]
[4,2,3,1]
[4,2,1,3]
[4,3,2,1]
[4,3,1,2]

我不想在这两个不同的开头或数字之间有一个 space。我只是为了便于阅读而添加的。

它不仅适用于 Integers,而且适用于字符串、我们的 类 等对象...

那么,如何在 Java 或 Kotlin 中实现这一点?


我也刚遇到 this post,但它需要两个数组,需要一个。还有就是关门了,感觉还是再问一个好。

您似乎希望生成所有可能的排列(N!),而不是给定对象集的组合。请检查番石榴的图书馆 Collections2.permutations.

它采用元素集合,return这些元素的列表集合。

public class Permutations {

public static void main(String[] args) {
    List<Integer> myList = List.of(1,2,3,4);
    // generate permutations of myList
    var permutations = Collections2.permutations(myList);
}

}

如果任务不是实现生成所需排列的算法,我建议使用像 combinatoricslib3 这样的库。如果你碰巧在你的项目中使用 Guava 或 Apache Commons,它们也有一些方法可以从给定的集合中生成组合/排列。使用 combinatoricslib3,您的代码可能类似于:

import org.paukov.combinatorics3.Generator;

public class Example {

    public static void main(String[] args) {
        Integer[] array = {1,2,3,4};
        Generator.permutation(array)
                .simple()
                .stream()
                .forEach(System.out::println);

        //Example with strings

        Generator.permutation("apple", "orange", "cherry")
                .simple()
                .stream()
                .forEach(System.out::println);
    }
}

输出:

[1, 2, 3, 4]
[1, 2, 4, 3]
[1, 4, 2, 3]
[4, 1, 2, 3]
[4, 1, 3, 2]
....

[apple, orange, cherry]
[apple, cherry, orange]
[cherry, apple, orange]
[cherry, orange, apple]
[orange, cherry, apple]
[orange, apple, cherry]

不使用库:

fun List<Any>.permutations(): List<List<Any>> {
  if (isEmpty()) return listOf(emptyList())
  return indices.fold(emptyList()) { result, i ->
    (result + (this - this[i])
      .permutations()
      .fold(mutableListOf()) { acc, item ->
        acc.add(item + this[i])
        acc
      }
    ).toMutableList()
  }
}

listOf(1, 2, 3, 4).permutations().forEach(::println)

listOf("A", "B", "C", "D").permutations().forEach(::println)

data class Test (val name: String)
listOf(Test("A"), Test("B"), Test("C"), Test("D")).permutations().forEach(::println)