Algorithm 在Scala中使用公共元素识别命名集的有效方法

Algorithm 在Scala中使用公共元素识别命名集的有效方法,algorithm,scala,set-intersection,Algorithm,Scala,Set Intersection,给定一个Map[String,Set[String]]在Scala中,在对应的集合有一个非空的交集的情况下,什么是一种优雅而有效的方法来确定所有不同键对的集合 例如,将地图修复为 val input = Map ( "a" -> Set("x", "z"), "b" -> Set("f") "c" -> Set("f", "z", "44") "d" -> Set("99") ) 那么所需的输出是 Set( ("a",

给定一个Map[String,Set[String]]在Scala中,在对应的集合有一个非空的交集的情况下,什么是一种优雅而有效的方法来确定所有不同键对的集合

例如,将地图修复为

  val input = Map (
    "a" -> Set("x", "z"),
    "b" -> Set("f")
    "c" -> Set("f", "z", "44")
    "d" -> Set("99")
  )
那么所需的输出是

  Set(
    ("a", "c"),
    ("b", "c")
  )

在这种情况下,高效意味着优于O(n^2),其中n是作为输入给定的集合族中元素数的总和。

悲观复杂性不可能比O(n^2)更好。请看以下示例:

Map(
  1 -> Set("a"),
  2 -> Set("a"),
  3 -> Set("a"),
  ...
  n -> Set("a")
)
在这种情况下,每对集合都有非空交点。因此,在这种情况下,输出的大小是O(n^2),因此无法获得更好的复杂性

显然,这并不意味着你不能想出比暴力更好的算法。例如,您可以将其转换为:

val input = Map (
  "a" -> Set("x", "z"),
  "b" -> Set("f")
  "c" -> Set("f", "z", "44")
  "d" -> Set("99")
)
为此:

val transformed = Map (
  "x" -> Set("a"),
  "z" -> Set("a", "c"),
  "f" -> Set("b", "c"),
  "44" -> Set("c"),
  "99" -> Set("d")
)
你可以在线性时间内完成。为此,我会使用Scala集合生成器或可变集合,以避免对不可变集合执行昂贵的操作


然后,您可以查看此转换映射中的每个值集,并为每个值生成所有可能的元素对。这可能需要O(n^2),但如果您的输出中没有很多对,那么速度会快得多。

@Calpis您可以放大您的建议吗?在大多数情况下,预期对的数量将是O(m),其中m是命名集的数量,因此这是一个可接受的解决方案。