首页 文章

在Kotlin中保持重复值的两个列表的交集

提问于
浏览
0

我想找到两个列表之间的公共元素的数量而不消除重复 .

例如:


输入: [1, 3, 3][4, 3, 3]

输出: 2 ,因为常见元素是 [3, 3]


输入: [1, 2, 3][4, 3, 3]

输出: 1 ,因为常见元素是 [3]


如果我使用Kotlin集合intersect,结果是一个集合,这将阻止我计算重复值 .

我发现(对于Python)this,它以不同方式处理重复项和this,这使我使用this实现,其中 ab 是列表:

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的收藏功能?也许是避免显式迭代的东西?

1 回答

  • 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()
    

相关问题