1

私はHaskellを学んでいて、ちょっと立ち往生しています。リスト要素を比較し、それらの違いを測定して、最も高いものを返したいと思います。残念ながら、その問題にアプローチする方法がわかりません。通常、私はリストを反復して隣接するものを比較するだけですが、Haskell ではそうではないようです。私はすでに使用してみmapましたが、私が言ったように、あなたがその問題をどのように解決できるか本当にわかりません. あらゆる種類のアドバイスに感謝します!

幸運をお祈りしています

編集: 私の考えは、最初にこのようなすべてのペアを圧縮することpairs a = zip a (tail a)です。map次に、すべての違いを取得して (おそらく?)、最も高いものを選択したいと思います。Haskell 構文を処理できません。

4

3 に答える 3

6

リスト要素間の「不一致を測定する」とはどういう意味かわかりませんが、リスト内の「最大の」要素を計算する場合は、組み込みmaximum関数を使用します。

maximum :: Ord a => [a] -> a

この関数は、順序付け可能な値のリストを取得するため、すべての数値、文字、および文字列が含まれます。

最大値と最小値の差を取得したい場合は、同様の関数を使用してminimum、2 つを減算するだけです。確かに、リストを 1 回だけトラバースするか、リストを並べ替えてから最初と最後の要素を取得するという、わずかに高速な解決策があるかもしれませんが、ほとんどの場合、それdiff xs = maximum xs - minimum xsは十分に高速であり、他の人にとって最も理にかなっています。


したがって、やりたいことは、各要素の最小値と最大値を計算するのではなく、連続する要素間の差を計算することです。直接インデックスを作成する必要はありませんが、 という便利な関数を使用してzipWithください。二項演算と 2 つのリストを取り、その二項演算を使用してそれらをまとめて「圧縮」します。だから何か

zipWith (+) [1, 2, 3] [4, 5, 6] = [1 + 4, 2 + 5, 3 + 6] = [5, 7, 9]

リストの 1 つが早く使い果たされた場合、そこで停止するため、かなり便利です。だからあなたは次のようなことができます

diff xs = zipWith (-) xs ???

しかし、リストを 1 オフセットするにはどうすればよいでしょうか。簡単な (そして安全な) 方法は、 を使用することdrop 1です。を使用することもできますが、 が空のリストのtail場合はエラーがスローされ、プログラムがクラッシュしますが、そうではありませんxsdrop

diff xs = zipWith (-) xs $ drop 1 xs

したがって、例は次のようになります

diff [1, 2, 3, 4] = zipWith (-) [1, 2, 3, 4] $ drop 1 [1, 2, 3, 4]
                  = zipWith (-) [1, 2, 3, 4] [2, 3, 4]
                  = [1 - 2, 2 - 3, 3 - 4]
                  = [-1, -1, -1]

この関数は正と負の値を返します。必要なのは大きさだけなので、次のabs関数を使用できます。

maxDiff xs = ??? $ map abs $ diff xs

そして、上で強調した関数を使用します。

maxDiff xs = maximum $ map abs $ diff xs

そして、あなたは完了です!派手になりたい場合は、これをポイントフリー表記で次のように書くこともできます。

maxDiff = maximum . map abs . diff

さて、これは実際にはエラーをスローするため、空のリストでmaximum []エラーを発生させますが、それを解決する方法を見つけさせます.

于 2013-12-11T19:06:36.557 に答える
1

map関数をリストにマップします。thing1リスト内のそれぞれを に変換しthing2ます。

あなたが望むのは、2 つの隣人の間の最大の違いを見つけることです。これは、map単独ではできません。今のところ数字だけを見ていると思います。その方が簡単だからです。

diffs :: (Num a) => [a] -> [a]
diffs [] = []
diffs [x] = []
diffs (x1:x2:xs) = abs(x1-x2) : (diffs$x2:xs)

mnd :: (Num a, Ord a) => [a] -> a
mnd [] = 0
mnd [x] = 0
mnd xs = maximum$diffs xs

したがってdiffs、各リスト項目を一度に 1 つずつ取得し、それとその隣接項目との絶対差を取得してから、それを作成するリストの先頭に配置します (:演算子は個々の要素をリストの先頭に配置します)。

mndmaximum$diffs xsスローされる例外を停止する単なるラッパーです。

于 2013-12-11T21:50:17.710 に答える