0

我已经定义了 (String, Int) 对的列表。

 type PatientList = [(String,Int)]

我需要以 'name' 和 'number' 的形式将数据添加到此列表中,其中 number 将随着列表中的每个添加而增加,例如添加 3 个名称后的列表(或元组)将如下所示:

 [("bob", 1), ("ted", 2), ("harry", 3)] 

将使用以下代码捕获名称:

  do putStr "You are? "
  name <- getLine

我目前的解决方案是创建一个名称列表,例如(bob、ted、harry),然后使用 zip,将这些列表组合如下:

 zip = [1...]["bob","ted","harry"]

该解决方案不能满足我的要求,因为我希望在不同时间添加到列表中而不是组合在一起。我怎样才能做到这一点?

4

3 回答 3

5

以相反的顺序保持列表不是更好吗?

[("harry", 3), ("ted", 2), ("bob", 1)]

比添加将在恒定时间内:

add :: PatientList -> String -> PatientList
add [] newName = [newName]
add ((oldName, x):xs) newName = (newName, x+1):(oldName, x):xs

当您需要按顺序排列整个列表时,您只需 O(lenght yourList) 线性时间:

reverse patientList
于 2013-03-18T13:28:43.587 回答
4

您可以使用包中的IntMap, containers

import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap

type PatientList = IntMap String

registerPatient :: PatientList -> String -> PatientList
registerPatient pList name
  | IntMap.null plist = IntMap.singleton 1 name  
  | otherwise         = let (n, _) = findMax pList 
                        in IntMap.insert (succ n) name plist
于 2013-03-18T13:23:24.123 回答
2

如前所述,如果速度不是问题,则使用长度

add :: String -> [(String, Int)] -> [(String, Int)]
add name xs = xs ++ [(name, length xs)]

但是如果你删除一个元素,这会弄乱你的身份,所以也许

add name xs = xs ++ [(name, 1 + ( snd (last xs) ) )]

我没有尝试运行任何这些,因为我不是带有 ghc 的计算机,但你应该明白这一点。

于 2013-03-18T13:23:24.520 回答