كيفية معرفة ما اذا كان سلسلة أصغر من الآخر، في حزقيل؟
سؤال
ولقد اثنين من سلاسل المعطاة كوسائط إلى وظيفة هاسكل.
وs1
أصغر من s2
إذا s1
أقصر من s2
أو إذا كان لديهم نفس الطول وs1
هو lexicographically أصغر من s2
.
وكيف يمكنني تنفيذ هذا في حزقيل؟
المحلول
وكنت استخدام شيء كما يلي:
smaller :: String -> String -> Bool
smaller s1 s2 | len1 /= len2 = (len1 < len2)
| otherwise = (s1 < s2)
where (len1, len2) = (length s1, length s2)
في ما يلي ملخص العينة، في العناق:
Main> smaller "b" "aa" True Main> smaller "aa" "b" False Main> smaller "this" "that" False Main> smaller "that" "this" True
نصائح أخرى
والحل مرور واحد:
lengthcompare :: Ord a => [a] -> [a] -> Ordering
lengthcompare = lc EQ
where
lc lx [] [] = lx
lc _ [] _ = LT
lc _ _ [] = GT
lc EQ (v:vs) (w:ws) = lc (compare v w) vs ws
lc lx (_:vs) (_:ws) = lc lx vs ws
smaller :: Ord a => [a] -> [a] -> Bool
smaller s1 s2 = lengthcompare s1 s2 == LT
وجرب هذا:
compare s1 s2
(وهذا يعود LT، EQ، أو GT).
ونسخة أقصر من النسخة mappend
توم Lokhorst أعلاه:
import Data.Monoid (mappend)
import Data.Ord (comparing)
compareStrings :: String -> String -> Ordering
compareStrings = comparing length `mappend` comparing id
وهناك طريقة أخرى، والاستفادة من ترتيب الصفوف:
import Data.Ord (comparing)
import Control.Arrow ((&&&))
compareStrings :: String -> String -> Ordering
compareStrings = comparing (length &&& id)
وString
هو مثيل Ord
و بالتالي يمكنك استخدامها كل من هذه الأساليب لمقارنة lexicographically السلسلة. كما قال أندرو، وهذا compare
أساسا ولكن أيضا عوامل المقارنة، (<)
وغيرها.
smaller :: Ord a => a -> a -> Bool
smaller a b = a < b
وهذا يعمل ل<م> جميع أنواع م> تنفيذ Ord
(وهو في الحقيقة مجرد مجمع الخام ل(<)
)، بما في ذلك String
.
وسلسلة العادية مقارنة يعمل فقط على ترتيب المعجمي، وليس طول السلاسل.
وهكذا كنت قد لكتابة وظيفة الخاصة بك للتحقق أيضا لطول:
smaller :: String -> String -> Bool
smaller s1 s2 | length s1 < length s2 = True
| length s1 > length s2 = False
| otherwise = s1 < s2
وأو أكثر قليلا عام:
compareStrings :: String -> String -> Ordering
compareStrings s1 s2 | length s1 < length s2 = LT
| length s1 > length s2 = GT
| otherwise = compare s1 s2
مثال:
ghci> compare "ab" "z"
LT
ghci> compareStrings "ab" "z"
GT
وكنا اللعب حولها مع Monoids في الجامعة الأسبوع الماضي، وتوصلنا مع هذه الحالة Ord
بديل جميل:
instance Ord a => Ord [a] where
compare = comparing length
`mappend` comparing head `mappend` comparing tail
ولكن إذا كنت لا أفهم تماما هذا، وأنا أقترح عليك العصا مع التعريف الأول؛ -)