到目前为止,我正试图在haskell中做分数背包问题
代码:
{- Input "how much can the knapsack hole <- x" "Possible items in sack [(label, value, weight), ...]" -}
knap x [] = []
knap x y = if length y == 1 then
输入列表的格式为[([Char],Integer,Integer),...]列表(列表,字符,整数和整数)。
我的问题是试图拉出可能放在背包中的每件物品的标签,价值和重量。 (从列表中拉出值)
在我的前奏&gt;提示我正在做一些尝试
ghci输出:
Prelude> let x = [("label 1", 2, 14), ("label 2", 1, 15)]
Prelude> :t x
x :: [([Char], Integer, Integer)]
Prelude> length x
2
Prelude> x !! 0
("label 1",2,14)
Prelude> x !! 0 !! 1
<interactive>:1:1:
Couldn't match expected type `[a0]'
with actual type `([Char], Integer, Integer)'
Expected type: [[a0]]
Actual type: [([Char], Integer, Integer)]
In the first argument of `(!!)', namely `x'
In the first argument of `(!!)', namely `x !! 0'
如你所见,我正在努力做清单!!索引!!索引尝试从“项目”中减轻重量。这样做的正确语法是什么?
答案 0 :(得分:2)
(a,b,c)
是一个元组,而不是列表。您不能在元组上使用!!
。毕竟:!!
的类型对于元组会是什么样的?
从元组中获取值的方法是使用这样的模式匹配:
let (name, x, y) = theTuple in
-- ...
模式匹配通常也是获取列表头部的首选方式。因此,处理元组列表的函数通常看起来像这样:
f [] = -- handle the empty list
f ((name, x, y) : rest) =
-- do something with name, x and y and then recurse on rest
答案 1 :(得分:2)
嗯,!!
运算符仅适用于列表,正如您可以从其类型签名中看到的那样:[a] -> Int -> a
。
如果您想坚持使用元组,可以使用fst
和snd
的样式为3元组定义自己的函数。你可以用模式匹配来做到这一点;类似的东西:
first :: (a,b,c) -> a
first (a,_,_) = a
但是,为项目设计数据类型可能更好,并使用记录来提取所需的字段。
data Item = Item { label :: String
value :: Int
weight :: Int
}
然后,要制作新项x
,您可以使用let x = Item {label = "label 1", value = 2, weight = 14}
现在您可以将背包建模为[Item]
类型的项目列表,并获取第一项的值,您可以使用value $ knapsack !! 0
,其中knapsack
是您的列表物品。