在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)]