Kotlin 如何在函数样式中生成特定长度的非穷举排列

Kotlin 如何在函数样式中生成特定长度的非穷举排列,kotlin,functional-programming,combinatorics,Kotlin,Functional Programming,Combinatorics,我试图创建一个函数,生成所有可能的长度为n的排列,其中列出的对象是从集合S中非穷尽地获取的。我试图以函数的方式使用Kotlin来实现这一点 这与Python的问题相同: 提供的答案是特定于Python的,因此对我没有帮助 我还发现: 但是我很难理解这是不是和我想做的一样 我已经编写了一个函数,接近完成任务,但它返回所有长度的非穷举排列您完成了困难的部分,现在只需在最后使用一个过滤器:-) 有趣的非穷举置换(长度:Int,组件:List):List{ 返回if(components.isEmpty

我试图创建一个函数,生成所有可能的长度为n的排列,其中列出的对象是从集合S中非穷尽地获取的。我试图以函数的方式使用Kotlin来实现这一点

这与Python的问题相同: 提供的答案是特定于Python的,因此对我没有帮助

我还发现: 但是我很难理解这是不是和我想做的一样


我已经编写了一个函数,接近完成任务,但它返回所有长度的非穷举排列您完成了困难的部分,现在只需在最后使用一个过滤器:-)

有趣的非穷举置换(长度:Int,组件:List):List{ 返回if(components.isEmpty()| | length 非穷举置换(长度-1,分量).map{y->listOf(x)+y} }.fold(listOf(listOf()){x,y->x+y} }.过滤器{ it.size==长度 } }
您可以这样做:

fun <T> nonexhaustivePermutations(length: Int, components: List<T>): List<List<T>> =
    if (components.isEmpty() || length <= 0) listOf(emptyList())
    else nonexhaustivePermutations(length - 1, components)
        .flatMap { sub -> components.map { sub + it } }
但除了显著提高性能外,这种交换还重新排序返回的元素。可以通过将
listOf(elm)+sub
替换为
sub+elm
来部分修复:

fun <T> nonexhaustivePermutations(length: Int, components: List<T>): List<List<T>> =
    if (components.isEmpty() || length <= 0) listOf(listOf())
    else nonexhaustivePermutations(length - 1, components).map { sub ->
        components.map { elm -> sub + elm }
    }.fold(listOf(listOf())) { result, elm -> result + elm }
此版本工作正常。但最后一行所做的唯一事情是列表展开。通过将
map
替换为
flatMap
,展开可以与映射相结合:

fun <T> nonexhaustivePermutations(length: Int, components: List<T>): List<List<T>> =
    if (components.isEmpty() || length <= 0) listOf(listOf())
    else nonexhaustivePermutations(length - 1, components).map { sub ->
        components.map { elm -> listOf(elm) + sub }
    }.fold(listOf(listOf())) { result, elm -> result + elm }
fun <T> nonexhaustivePermutations(length: Int, components: List<T>): List<List<T>> =
    if (components.isEmpty() || length <= 0) listOf(listOf())
    else nonexhaustivePermutations(length - 1, components).flatMap { sub ->
        components.map { elm -> sub + elm } 
    }
有趣的非穷举置换(长度:Int,组件:List):List= if(components.isEmpty()|长度 components.map{elm->sub+elm} }
谢谢!我仍然想知道这是否是一种有效的方法。在我看来,生成额外列表只是为了以后过滤它们,这是不必要的工作。谢谢你,这正是我想要的!你有什么见解可以分享我最初尝试时的错误吗?@EmilJansson给我一些时间,我会告诉你I’我会在我的答案中加上对你错误的解释。哇,这太棒了!谢谢你的详细回答!
fun <T> nonexhaustivePermutations(length: Int, components: List<T>): List<List<T>> =
    if (components.isEmpty() || length <= 0) listOf(listOf())
    else nonexhaustivePermutations(length - 1, components).map { sub ->
        components.map { elm -> listOf(elm) + sub }
    }.fold(listOf(listOf())) { result, elm -> result + elm }
fun <T> nonexhaustivePermutations(length: Int, components: List<T>): List<List<T>> =
    if (components.isEmpty() || length <= 0) listOf(listOf())
    else nonexhaustivePermutations(length - 1, components).map { sub ->
        components.map { elm -> sub + elm }
    }.fold(listOf(listOf())) { result, elm -> result + elm }
fun <T> nonexhaustivePermutations(length: Int, components: List<T>): List<List<T>> =
    if (components.isEmpty() || length <= 0) listOf(listOf())
    else nonexhaustivePermutations(length - 1, components).map { sub ->
        components.map { elm -> sub + elm }
    }.fold(emptyList()) { result, elm -> result + elm }
fun <T> nonexhaustivePermutations(length: Int, components: List<T>): List<List<T>> =
    if (components.isEmpty() || length <= 0) listOf(listOf())
    else nonexhaustivePermutations(length - 1, components).flatMap { sub ->
        components.map { elm -> sub + elm } 
    }