scala - Scala 中集合的交集
问题描述
我HashMap
在 Scala 中有以下形式:
HashMap(
37 -> HashSet(5, 1, 6, 9, 13, 12, 3, 8, 4),
20 -> HashSet(5, 1, 6, 9, 13, 12, 3, 8, 4),
45 -> HashSet(5, 6, 9, 13, 3, 8, 4),
49 -> HashSet(5, 6, 9, 13, 3, 8, 4),
39 -> Set(5, 12, 3, 9),
31 -> HashSet(5, 6, 9, 13, 3, 8, 4),
15 -> Set(5, 9, 3),
28 -> Set(5, 3, 9),
21 -> HashSet(5, 6, 9, 13, 3, 8, 4),
33 -> Set(9, 3),
40 -> HashSet(5, 1, 6, 9, 13, 12, 3, 8, 4),
26 -> Set(9, 3, 5),
55 -> Set(6, 4, 8),
23 -> Set(9, 5, 3, 12),
36 -> Set(7, 2),
19 -> Set(5, 9, 3))
获取地图中所有集合的交集的最有效方法是什么?
问题是这些映射和集合可能会变得很大,并且在递归算法中需要大量的交集(一次执行中最多调用 10K 次),而For comprehension
Scala 中的方法并没有有效地解决这个问题。
编辑 :
至于For comprehension
我只是做了一个简单的函数来计算它(它有一个可以优化的无用交集,第一个,与大量调用无关。我也可以在交集为空时停止计算,但很少发生但我避免空值的交集,因为理论上在我的算法中,地图不应该有空值的键:
def stateIntersection(m: Map[Int, Set[Int]]): Set[Int] = {
var acc = m.head._2
for ((k, v) <- m) {
if (v.nonEmpty)
acc = acc.intersect(v)
}
acc
}
解决方案
您的集合中的值是否有下限和上限?如果他们这样做,并且范围相当小(例如,0..1000),一种有效的方法(在任何语言中)可能是创建一个固定大小的数组 int[0..1000],然后遍历所有集合并增加相应的数组元素。这是一个恒定时间操作,不像在集合中搜索,这将不可避免地成为上述算法的一部分。
counters = int[1000] // assuming it's initialized with 0's
for set in sets {
for element in set.elements {
counters[element]++
}
}
然后,您只需收集值等于集合数的数组元素。
推荐阅读
- python - 在 Mac OS 上安装 Python 模块
- .htaccess - 使用 cloudflare SSL 时如何不重定向 Twitterbot?
- java - 通过Java设置springboot logback根记录器级别不起作用
- user-interface - 重新创建 Pinterest UI Flutter
- c# - 关闭代码文件时自动折叠区域
- angular - 带有可重用子组件示例的 Angular 8 反应式表单
- notepad++ - 大型 .A2L 文件,引用的翻译问题
- mysql - MySQL:如何在客户端和服务器端都启用本地加载数据
- angular - 对返回 ValidatorFn[] 类型的函数进行单元测试
- php - 当我在其他文件中调用它们时,类静态变量会重置