Haskell中的邻接矩阵到边缘列表

时间:2014-07-04 14:56:04

标签: list haskell graph multidimensional-array adjacency-matrix

我有1d锦标赛队伍和2d“对手矩阵”。

我只想提取每个队伍的对手名单。

我只是在学习Haskell并想知道,如果有人能想到下面已经运行的代码更优雅的解决方案。 ......也许列表理解? ...

代码:

findOp :: (Eq a, Num a) => [b] -> [a] -> [b]
findOp (x:xs) (y:ys) | y == 1 = [x] ++ findOp xs ys
                     | otherwise = findOp xs ys

findOp [] [] = []

tab = [[0,1,0,1],
       [1,0,1,0],
       [0,1,0,1],
       [1,0,1,0]]

teams = ["team a",
         "team b",
         "team c",
         "team d" ]

main :: IO ()
main = do
       let games = map (\x -> (fst x, findOp teams $ snd x)) $ zip teams tab
       putStrLn $ show games

结果:

[("team a",["team b","team d"]),("team b",["team a","team c"]),("team c",["team b","team d"]),("team d",["team a","team c"])]

1 个答案:

答案 0 :(得分:5)

无论如何,假设这很快就会迁移,这是一个答案:

tab = [[0,1,0,1],
       [1,0,1,0],
       [0,1,0,1],
       [1,0,1,0]]

teams = ["team a",
         "team b",
         "team c",
         "team d" ]

main = do
    let matches = zip teams . map (map fst . filter ((== 1) . snd) . zip teams) $ tab
    print matches

关键洞察力始于map (zip teams) tab。这将为您提供矩阵内的团队名称以及值。从那里开始,其余的是简单的数据操作 - 以及手动融合映射在每个内部列表上的三个操作。

顺便说一句 - 这实际上是将邻接矩阵转换为边缘列表的一般问题的具体示例。在软件中使用图形表示时,这是最简单,最基本的操作之一。