List Kotlin生成列表的排列(按顺序),无重复元素

List Kotlin生成列表的排列(按顺序),无重复元素,list,kotlin,permutation,List,Kotlin,Permutation,是否有一种简单(甚至可能是Kotlin方法)来生成给定列表(包含重复元素)的所有排列,其: 保持元素的顺序 删除所有重复的元素 包括所有元素 例如: 鉴于清单:[A,B,C,A,B,D,A],我预计会有以下结果: [A,B,C,D],[A,C,B,D],[B,C,A,D],[C,A,B,D],[C,B,A,A],[B,C,D,A], …(如果还有其他组合) 以下结果无效: [A,B,C,A,D](重复A) [A,B,C,A](重复的A和缺失的D) [A,C,D,B](顺序错误) 谢谢你的帮助

是否有一种简单(甚至可能是Kotlin方法)来生成给定列表(包含重复元素)的所有排列,其:

  • 保持元素的顺序
  • 删除所有重复的元素
  • 包括所有元素
例如:

鉴于清单:
[A,B,C,A,B,D,A]
,我预计会有以下结果:

[A,B,C,D]
[A,C,B,D]
[B,C,A,D]
[C,A,B,D]
[C,B,A,A]
[B,C,D,A]
(如果还有其他组合)

以下结果无效:

[A,B,C,A,D]
(重复A)

[A,B,C,A]
(重复的A和缺失的D)

[A,C,D,B]
(顺序错误)

谢谢你的帮助。

fun main(){
val list=listOf('A','B','C','A','B','D','A')
generatePermutations(列表,::println)
}
/**
*生成问题中描述的所有排列
*为了性能起见,它为每个置换调用[onNextPermutation],
*但它使用相同的列表来写排列,
*因此,如果您需要在其他地方使用这些排列,请自行复制其参数
*/
fun generatePermutations(元素列表:列表,onExtPermutation:(列表)->Unit){
if(elementsList.isEmpty()){
onNextPermutation(emptyList())
返回
}
val elementCounts=LinkedHashMap()//我们需要记住元素添加到映射的顺序
元素列表forEach{
elementCounts[it]=1+(elementCounts[it]?:0)//计算我们的元素
}
val DifferentialElements=elementCounts.keys
val TotalPermutationScont=elementCounts.values.fold(1){a,b->a*b}
//为了提高性能,接下来的3个集合通过生成器循环重用
val takenntrynumbers=LinkedHashMap()//我们将带到下一个置换的每个元素的条目数
differentElements.forEach{takenEntryNumbers[it]=0}
val entriesOfElementViewed=HashMap()//迭代elementsList时已查看的每个元素的条目数
differentElements.forEach{EntriesFelementView[it]=0}
val currentPermutation=ArrayList()//我们将使用可变列表写入置换
重复(differentElements.size){currentPermutation.add(elementsList[0])}//只需将其填充到所需的大小即可
重复(TotalPermutationScont){//生成下一个置换
var entriesTaken=0//此排列中的条目总数
对于(elementsList中的元素){//生成当前置换
如果(EntriesFelementViewed[element]==TakenEntryNumber[element]){
currentPermutation[entriesTaken++]=元素
}
EntriesFelementView[元素]=1+(EntriesFelementView[元素]?:0)
}
onNextPermutation(当前置换)
//更新集合以开始下一次排列
differentElements.forEach{EntriesFelementView[it]=0}
//生成条目号的下一个排列,其中每个条目号小于元素的总计数
对于(不同元素中的元素){
如果(1+(takenEntryNumbers[元素]?:0)=元素计数[元素]){
takenEntryNumbers[元素]=0
}
否则{
takenEntryNumbers[元素]=1+(takenEntryNumbers[元素]?:0)
打破
}
}
}
}
输出:

[A、B、C、D]

[B、C、A、D]

[B、C、D、A]

[A、C、B、D]

[C、A、B、D]

[C、B、D、A]


解决了O(listSize*PermutationScont)中每个列表泛型类型的问题。

这里有一种方法可以以某种功能性的方式完成

它首先收集一组不同值的“指令”,这些值与应该保留的出现索引成对。为此,它将唯一值映射到它们的出现计数。然后它将它们折叠成一个包含所有可能的配对组合的列表。折叠操作从一组空排列开始,然后每个唯一值将其所有可能保留的索引与现有排列集相乘

然后,我们遍历所有指令集以应用这些指令:从原始列表的副本中删除除一个之外的所有唯一值

fun <T> getPermutationsWithDistinctValues(original: List<T>): Set<List<T>> {
    if (original.isEmpty())
        return emptySet()
    val permutationInstructions = original.toSet()
        .map { it to original.count { x -> x == it } }
        .fold(listOf(setOf<Pair<T, Int>>())) { acc, (value, valueCount) ->
            mutableListOf<Set<Pair<T, Int>>>().apply {
                for (set in acc) for (retainIndex in 0 until valueCount) add(set + (value to retainIndex))
            }
        }
    return mutableSetOf<List<T>>().also { outSet ->
        for (instructionSet in permutationInstructions) {
            outSet += original.toMutableList().apply {
                for ((value, retainIndex) in instructionSet) {
                    repeat(retainIndex) { removeAt(indexOfFirst { it == value }) }
                    repeat(count { it == value } - 1) { removeAt(indexOfLast { it == value }) }
                }
            }
        }
    }
}
fun GetPermutationSwithDistinctValue(原始:列表):设置{
if(original.isEmpty())
返回清空集()
val permutationInstructions=original.toSet()
.map{it to original.count{x->x==it}
.fold(listOf(setOf()){acc,(value,valueCount)->
mutableListOf().apply{
for(在acc中设置)for(在0中保留索引,直到valueCount)add(设置+(保留索引的值))
}
}
返回mutableSetOf()。同时{start->
for(排列指令中的指令起始){
start+=original.toMutableList().apply{
用于指令开始中的((值,保留索引){
重复(retainIndex){removeAt(indexOfFirst{it==value}}
重复(count{it==value}-1){removeAt(indexOfLast{it==value})}
}
}
}
}
}
我认为复杂性是O(n*mn),其中n是不同值的数量,m是不同值的最高重复。与另一个答案相同,因为最坏情况下的排列数是mn。

fun getUniquePermutation(array:array):List{
var permutationList=mutableListOf()
for(数组中的i.toSet()){
对于(数组中的j.toSet()){
排列列表。添加((i作为T到j作为T))
}
}
//println(排列列表)
返回置换列表
}
试着这样做
fun <T> getPermutationsWithDistinctValues(original: List<T>): Set<List<T>> {
    if (original.isEmpty())
        return emptySet()
    val permutationInstructions = original.toSet()
        .map { it to original.count { x -> x == it } }
        .fold(listOf(setOf<Pair<T, Int>>())) { acc, (value, valueCount) ->
            mutableListOf<Set<Pair<T, Int>>>().apply {
                for (set in acc) for (retainIndex in 0 until valueCount) add(set + (value to retainIndex))
            }
        }
    return mutableSetOf<List<T>>().also { outSet ->
        for (instructionSet in permutationInstructions) {
            outSet += original.toMutableList().apply {
                for ((value, retainIndex) in instructionSet) {
                    repeat(retainIndex) { removeAt(indexOfFirst { it == value }) }
                    repeat(count { it == value } - 1) { removeAt(indexOfLast { it == value }) }
                }
            }
        }
    }
}
fun <T>getUniquePermutation( array: Array< in T>): List<Pair<T,T>>{
    var permutationList = mutableListOf<Pair<T,T>>()
    for (i in array.toSet()){
        for (j in array.toSet()){
            permutationList.add((i as T to j as T))
        }
    }
   // println(permutationList)
    return permutationList
}
fun <T> allPermutations(set: Set<T>): Set<List<T>> {
    if (set.isEmpty()) return emptySet()

    fun <T> _allPermutations(list: List<T>): Set<List<T>> {
        if (list.isEmpty()) return setOf(emptyList())

        val result: MutableSet<List<T>> = mutableSetOf()
        for (i in list.indices) {
            _allPermutations(list - list[i]).forEach{
                item -> result.add(item + list[i])
            }
        }
        return result
    }

    return _allPermutations(set.toList())
}