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

时间:2013-05-30 22:18:36

标签: 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", "c"),
    ("b", "c")
  )

在此上下文中有效意味着优于O(n ^ 2),其中n是作为输入给出的集合族中元素数的总和。

1 个答案:

答案 0 :(得分:2)

你不能比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)但是如果你的输出中没有很多对,那么它会快得多。