保留Kotlin中重复值的两个列表的交集 [英] Intersection of two lists maintaining duplicate values in Kotlin

查看:87
本文介绍了保留Kotlin中重复值的两个列表的交集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to find the number of common elements between two lists without eliminating duplicates.

例如:

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

输出:2,因为公共元素是[3, 3]

output: 2, since the common elements are [3, 3]

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

输出:1,因为公共元素是[3]

output: 1, since the common elements are [3]

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

If I were to use the Kotlin collections intersect, the result is a set, which will prevent me from counting duplicate values.

我发现(对于Python),它可以处理重复项和不同,这导致我使用

I found (for Python) this, which handles duplicates differently and this, which led me to use this implementation, where a and b are the lists:

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的全部馆藏功能吗?也许是避免明确迭代的东西?

However, being new to Kotlin I'm wondering if there's a more "Kotlin-y" way to do this--something taking advantage of all Kotlin's collections functionality? Maybe something that avoids explicitly iterating?

推荐答案

此:

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

它使用两个列表的交集,并通过遍历其每个项目,将两个列表中该项目的最小出现次数添加到计数器.

通过此导入:

It uses the intersection of the 2 lists and by iterating through each of its items, adds to the counter the minimum number of occurrences of the item in both lists.

With this import:

import kotlin.math.min

您可以避免在每次迭代时创建列表,并简化为:

you can avoid the creation of a list at each iteration and simplify to:

a.intersect(b).forEach { x-> counter += min(a.count {it == x}, b.count {it == x}) } 


由Arjan提供,这是一种更优雅的计算总和的方法:


Courtesy of Arjan, a more elegant way to calculate the sum:

val result = a.intersect(b).map { x -> min(a.count {it == x}, b.count {it == x}) }.sum()

这篇关于保留Kotlin中重复值的两个列表的交集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆