Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ArrayList[Kotlin]中组合元素_Kotlin - Fatal编程技术网

在ArrayList[Kotlin]中组合元素

在ArrayList[Kotlin]中组合元素,kotlin,Kotlin,我有一个元素的数组列表,我需要它来获得对的组合 例如,[A,B,C]将转换为[[A,B],[A,C],[B,C] 我目前使用正常的方法来实现这一点 for(i in 0 until arr.size-1) for(j in i+1 until arr.size) //do stuff with arr[i], arr[j] 如果我需要两个以上元素的组合,我可能会编写一个递归函数来实现同样的功能。我担心的是,这种方法仍然是老派的&可能不像Kotlin那样实用 有没有更好的

我有一个元素的数组列表,我需要它来获得对的组合

例如,
[A,B,C]
将转换为
[[A,B],[A,C],[B,C]

我目前使用正常的方法来实现这一点

for(i in 0 until arr.size-1)
    for(j in i+1 until arr.size)
        //do stuff with arr[i], arr[j]
如果我需要两个以上元素的组合,我可能会编写一个递归函数来实现同样的功能。我担心的是,这种方法仍然是老派的&可能不像Kotlin那样实用


有没有更好的方法来实现这一点&也就是在不进入递归的情况下组合更多的元素?

要使其更具功能性,可以做的一件事是将成对的产生与它们的消耗解耦

可以使用函数
序列
写入配对生成器:

fun <T> elementPairs(arr: List<T>): Sequence<Pair<T, T>> = sequence {
    for(i in 0 until arr.size-1)
        for(j in i+1 until arr.size)
            yield(arr[i] to arr[j])
}

您可以在这里尝试:

这样接受的答案就可以创建对。我创建了一个对象,该对象可以处理到items.size-1的任何长度组合

class CombinationGenerator<T>(private val items: List<T>, choose: Int = 1) : Iterator<List<T>>, Iterable<List<T>> {
    private val indices = Array(choose) { it }
    private var first = true

    init {
        if (items.isEmpty() || choose > items.size || choose < 1)
            error("list must have more than 'choose' items and 'choose' min is 1")
    }

    override fun hasNext(): Boolean = indices.filterIndexed { index, it ->
        when (index) {
            indices.lastIndex -> items.lastIndex > it
            else -> indices[index + 1] - 1 > it
        }
    }.any()

    override fun next(): List<T> {
        if (!hasNext()) error("AINT NO MORE WHA HAPPEN")
        if (!first) {
            incrementAndCarry()
        } else
            first = false
        return List(indices.size) { items[indices[it]] }
    }

    private fun incrementAndCarry() {
        var carry = false
        var place = indices.lastIndex
        do {
            carry = if ((place == indices.lastIndex && indices[place] < items.lastIndex)
                    || (place != indices.lastIndex && indices[place] < indices[place + 1] - 1)) {
                indices[place]++
                (place + 1..indices.lastIndex).forEachIndexed { index, i ->
                    indices[i] = indices[place] + index + 1
                }
                false
            } else
                true
            place--
        } while (carry && place > -1)
    }

    override fun iterator(): Iterator<List<T>> = this
}

fun main() {
    val combGen = CombinationGenerator(listOf(1, 2, 3, 4), 3)
    combGen.map { println(it.joinToString()) }

}
class组合生成器(private-val-items:List,choose:Int=1):迭代器,Iterable{
私有值索引=数组(选择){it}
private var first=true
初始化{
如果(items.isEmpty()| | choose>items.size | | choose<1)
错误(“列表必须包含多个“选择”项,且“选择”最小值为1”)
}
override fun hasNext():Boolean=index.filterIndexed{index,it->
何时(索引){
index.lastIndex->items.lastIndex>it
else->index[index+1]-1>它
}
}.any()
覆盖乐趣下一步():列表{
如果(!hasNext())错误(“不会再发生什么”)
如果(!第一个){
递增和进位()
}否则
第一个=错误
返回列表(index.size){items[index[it]]}
}
私人娱乐增量和携带(){
var进位=假
var place=index.lastIndex
做{
进位=if((place==index.lastIndex&&index[place]
指数[i]=指数[地点]+指数+1
}
假的
}否则
真的
放置--
}while(携带和放置>-1)
}
重写有趣的迭代器():迭代器=此
}
主要内容(){
val combGen=组合生成器(列表(1,2,3,4),3)
combGen.map{println(it.joinToString())}
}
输出

1 3
1 4
2 3
2 4
3 4
[(A, B), (A, C), (A, D), (B, C), (B, D), (C, D)]

你为什么害怕递归?Kotlin编译器能够使用关键字
tailrec
优化递归函数,而不会出现堆栈溢出的风险。请在“谢谢”上查找详细信息,我并不担心。我目前正在学习Kotlin,我想知道是否有一个语言特性,或者是集合中的预定义函数,以便我更好地理解Kotlin及其库!将逻辑解耦确实使其更加优雅。也许我可以将其作为任何
Iterable
类的扩展来编写。
1 3
1 4
2 3
2 4
3 4
val arr = arrayListOf("A", "B", "C", "D")
val list= mutableListOf<Pair<String, String>>()

arr.indices.forEach() { 
    i -> arr.indices.minus(0..i).forEach() { 
    j -> list.add(arr[i] to arr[j]) }
}
println(list)
[(A, B), (A, C), (A, D), (B, C), (B, D), (C, D)]