كيفية معرفة ما اذا كان سلسلة أصغر من الآخر، في حزقيل؟

StackOverflow https://stackoverflow.com/questions/819620

  •  03-07-2019
  •  | 
  •  

سؤال

ولقد اثنين من سلاسل المعطاة كوسائط إلى وظيفة هاسكل.

و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

ولكن إذا كنت لا أفهم تماما هذا، وأنا أقترح عليك العصا مع التعريف الأول؛ -)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top