0

これまでのところ、ハスケルで分数ナップザック問題を実行しようとしています

コード:

{- 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), ... ] (文字、整数、および整数のリスト) のリストのリストです。

私の問題は、ナップザックに入れる可能性のある各アイテムのラベル、値、および重量を引き出そうとしていることです。(リストのリストから値を引き出す)

私の prelude> プロンプトで、私はいくつかのことを試しています

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'

ご覧のとおり、私はリストをやろうとしています!! 索引 !!「アイテム」から重みを引き離そうとするインデックス。これを行うための適切な構文は何ですか?

4

2 に答える 2

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
于 2012-07-30T17:17:03.870 に答える
2

さて、この!!演算子は、その型シグネチャからわかるように、リストに対してのみ機能します: [a] -> Int -> a.

タプルに固執したい場合は、fstとのスタイルで 3 タプル用の独自の関数を定義できますsnd。これはパターン マッチングで行うことができます。何かのようなもの:

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で、アイテムのリストです。

于 2012-07-30T17:20:03.017 に答える