我想找到两个列表之间共有元素的数量而不消除重复。
例如:
输入:[1, 3, 3]
和[4, 3, 3]
输出:2
,因为公共元素是[3, 3]
输入:[1, 2, 3]
和[4, 3, 3]
输出:1
,因为公共元素是[3]
如果我要使用Kotlin集合intersect,则结果是一个集合,这将阻止我计算重复值。
我发现(对于Python)this和this处理不同的重复项,而this则导致我使用{{3}}实现,其中a
和b
是列表:
val aCounts = a.groupingBy { it }.eachCount()
val bCounts = b.groupingBy { it }.eachCount()
var intersectionCount = 0;
for ((k, v) in aCounts) {
intersectionCount += Math.min(v, bCounts.getOrDefault(k, 0))
}
但是,对于Kotlin来说我是新手,我想知道是否还有更多的“ Kotlin-y”方式可以做到这一点-可以利用Kotlin的全部馆藏功能吗?也许是避免明确迭代的东西?
答案 0 :(得分:2)
此:
val a = listOf(1, 2, 3, 3, 4, 5, 5, 5, 6)
val b = listOf(1, 3, 3, 3, 4, 4, 5, 6, 6, 7)
var counter = 0
a.intersect(b).forEach { x -> counter += listOf(a.count {it == x}, b.count {it == x}).min()!! }
println(counter)
将打印
6
它使用2个列表的交集,并通过遍历其每个项目,将两个列表中该项目的最小出现次数添加到计数器。
通过此导入:
import kotlin.math.min
您可以避免在每次迭代时创建列表,并简化为:
a.intersect(b).forEach { x-> counter += min(a.count {it == x}, b.count {it == x}) }
由Arjan提供,这是一种更优雅的计算总和的方法:
val result = a.intersect(b).map { x -> min(a.count {it == x}, b.count {it == x}) }.sum()
答案 1 :(得分:0)
从两个或多个数组列表中获取公共元素
输入
输出 = {1, 2, 2, 4, 6}
fun main() {
val array = ArrayList<ArrayList<String>>()
val arr1 = arrayListOf("1", "2", "2", "4", "5", "6")
val arr2 = arrayListOf("1", "2", "2", "4", "5", "6")
val arr3 = arrayListOf("1", "2", "2", "4", "6")
array.add(arr1)
array.add(arr2)
array.add(arr3)
println(getCommonElements(array)) }
创建一个用于存储arrayIndex和elementIndex的数据类
internal class IndexArray(val arrayIndex: Int,
val elementIndex: Int)
获取公共元素的算法
fun getCommonElements(arrayList: ArrayList<ArrayList<String>>): ArrayList<String> {
val commonElements = ArrayList<String>()
var isContain = true
val firstArray = arrayList[0]
val indexArray = ArrayList<IndexArray>()
// for loop for firstArray
for (e in firstArray) {
var elementIndex: Int
var arrayIndex: Int
// for loop for next ArrayList
for (i in 1 until arrayList.size) {
if (!arrayList[i].contains(e)) {
isContain = false
break
} else {
elementIndex = arrayList[i].indexOf(e)
arrayIndex = i
indexArray.add(IndexArray(arrayIndex, elementIndex))
}
}
if (isContain) {
commonElements.add(e)
// remove element
for (i in 0 until indexArray.size) {
arrayList[indexArray[i].arrayIndex].removeAt(indexArray[i].elementIndex)
}
indexArray.clear()
} else {
indexArray.clear()
isContain = true
}
}
return commonElements }