10

リストが連続して順序付けられているかどうかを確認できるライブラリ関数はHaskellにありますか?例えば。[1,2,3,4]は有効、[1,2,3,10]は無効です。

基本的に、3〜5要素の範囲のリストを作成でき、そのリストが連続して順序付けられているかどうかを確認しようとしています。

私の試み(これがそれに近づく正しい方法であるかどうかはわかりませんが、繰り返しが多すぎるようです)

isSucc:: [Integer] -> Bool
isSucc[]            = True
isSucc(x:y:zs)      = 
    if (x+1) == y
    then True && isSucc(y:zs)
    else isSucc(y:zs)

この機能を動作させた後、リストのリストをフィルタリングするためにこの機能を使用することを計画しています(リストをリスト内に保持し、連続して並べ替えられた場合のみ)

4

6 に答える 6

14

このトリックを使用して、リスト要素の連続するペアzipWith f xs (drop 1 xs)に適用できます。f(リストが空の場合、後者は失敗するため、drop 1ではなく注意してください!)tail

に置き換えるfと、値<=のリストが表示されBoolます。次に、それらがすべてであるかどうかを確認しますTrue

isSucc xs = and $ zipWith (<=) xs (drop 1 xs)
于 2013-03-21T08:22:40.507 に答える
9

そのための標準機能はありません。

関数の修正バージョンを次に示します。これにより、関数が汎用化され、冗長な条件が削除され、不足している条件が追加されます。

isSucc :: (Enum a, Eq a) => [a] -> Bool
isSucc [] = True
isSucc (x:[]) = True
isSucc (x:y:zs) | y == succ x = isSucc $ y:zs
isSucc _ = False
于 2013-03-21T08:25:42.467 に答える
5

私は、 MathematicalOrchidによって提供されているものよりも少し読みやすいソリューションを使用することを好みます。

まず最初に、多くの異なる状況で役立つ可能性のある功利主義関数をペアごとに定義します。

pairwise xs = zip xs $ tail xs

またはより現代的な方法で:

import Control.Applicative ((<*>))

pairwise = zip <*> tail

次に、他のコンビネータで使用します。

isSucc xs = all (\(x,y) -> succ x == y) $ pairwise xs
于 2013-03-21T12:18:56.827 に答える
0

連続するすべての差が1に等しいことを確認する場合は、次を使用できます。

isIncreasingByOne ::(Eq a、Num a)=> [a]-> Bool isIncreasingByOne = all(== 1)(zipWith(-)(tail xs)xs)

これは、およびを含む数値タイプ(したがってNum a制約)に対して機能します。たとえば、シーケンスが一度に5を超えて増加していることを確認したい場合にも、簡単に適応できます。FloatDouble

于 2013-03-21T17:28:13.640 に答える
0

別の方法があります、

isOrdered :: (Enum a, Eq a) => (a -> a -> Bool) -> [a] -> Bool
isOrdered op (a:b:ls) = op a b && isOrdered op (b:ls)
isOrdered op _ = True

したがって、

isSucc = isOrdered ((==) . succ)
于 2013-03-21T13:24:53.347 に答える
0

-これは注文されたかどうかをチェックします

isordd:: [Int] -> Bool 
isordd [] = True
isordd (x:y:xs) 
 | x > y = False
 | lengh xs == 0 = True
 | otherwise = isordd (y:xs)

-これはリストの長さを計算します

lengh::[Int]->Int
lengh [] = 0
lengh (x:xs) = 1+lengh xs
于 2019-04-07T18:42:30.410 に答える