【问题标题】:How can this Haskell combination algorithm be improved?这个 Haskell 组合算法如何改进?
【发布时间】:2016-01-07 23:10:39
【问题描述】:

如何改进以下问题的解决方案?能不能在时间和空间上更有效率?有没有空间泄漏?

问题: 给定一个Astronauts 的输入列表,生成一个Astronauts 对的列表,使得这些对没有来自同一国家/地区的两个Astronauts。假设输入有一个 Astronauts 列表和唯一的 identifiers。

data Astronaut = Astronaut { identifier :: Int, country :: String } deriving (Eq)

astronautPairs :: [Astronaut] -> [(Astronaut, Astronaut)]
astronautPairs xs = foldl accumulatePairs [] [(a, b) | a <- xs, b <- xs, country a /= country b]
    where
        accumulatePairs pairs pair = if hasPair pair pairs then pairs else pair:pairs
        hasPair pair@(a,b) ((c,d):xs) = a == d && b == c || hasPair pair xs
        hasPair _ [] = False

【问题讨论】:

  • 您认为应该占用多少空间?一旦你决定了,只需在一个大的输入上运行你的代码,看看你的内存使用是否匹配(-stderr 运行时选项可以在这里派上用场)。然后你告诉我们它是否有空间泄漏。
  • 您可能会喜欢one of my previous answers 中的pairs 函数。
  • 您想同时制作(a,b)(b,a),还是打算代表两人团队?

标签: haskell ghc


【解决方案1】:

与其消除翻转对,不如一开始就避免生成它们。是 我们 生产它们的,是吗?

import Data.List (tails)

astronautPairs :: [Astronaut] -> [(Astronaut, Astronaut)]
astronautPairs xs = [ (y,z) | (y:ys) <- tails xs, z <- .... , country y /= country .... ]

这假设宇航员的输入列表没有重复项。

因此,我们通过三角生成避免了重复。

(我留下了一部分代码,供您完成)。

【讨论】:

  • 是的,这对我来说是正确的。这个空间复杂度是多少?
  • 时间当然是二次的。空间将取决于最终列表的长度。除了必须完全存在于内存中的输入列表的 O(n) 大小之外,没有什么能阻止编译器编写在 O(1) 空间中工作的代码——即这不是在线的算法,即使访问了最后一个元素,GC也无法回收列表的头元素。
【解决方案2】:

让我们从实现细节退一步,想想你想要完成什么:

生成Astronauts 对的列表,使得这些对没有来自同一国家/地区的两个Astronauts

您似乎可以假设每个宇航员在列表中只出现一次。

解决此问题的一种有效方法是从按国家/地区划分您的列表开始。一个自然的方法是建立一个HashMap String [Int],其中包含来自每个国家的所有宇航员的列表。

import qualified Data.HashMap.Strict as HMS
import Data.HashMap.Strict (HashMap)

divideAstronauts :: [Astronaut] -> HashMap String [Int]
divideAstronauts = foldl' go mempty where
  go hm (Astronaut ident cntry) = HMS.insertWith (++) cntry [ident] hm

现在您可以将程序的其余部分分为两个步骤:

  1. 选择所有成对的国家/地区。
  2. 对于每一对国家,选择所有对宇航员,使每一对都来自其中一个国家。

【讨论】:

    猜你喜欢
    • 2020-04-18
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 2011-02-15
    • 1970-01-01
    • 2020-02-09
    相关资源
    最近更新 更多