2009-05-04 16 views

回答

9

我會使用類似以下內容:

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 
5

試試這個:

compare s1 s2 

(這將返回LT,EQ或GT)。

+0

我認爲OP希望較短的字符串比較長的字符串「小」,而不管它們的內容如何。比較「b」「aa」返回GT,但我認爲OP會希望在這種情況下返回LT的函數。 – 2009-05-04 12:19:02

2

StringOrd的一個實例,因此您可以使用所有這些方法按字典順序比較字符串。正如Andrew所說,這基本上是compare,但也包括比較運算符(<)等等。

smaller :: Ord a => a -> a -> Bool 
smaller a b = a < b 

這適用於各類實施Ord(實際上只是爲(<)粗包裝),包括String

+0

我認爲OP希望較短的字符串比較長的字符串「小」,而不管它們的內容如何。例如,較小的「b」「aa」應該返回True。 (<)沒有考慮到長度,所以我不相信你的回答完全是OP要求的。 – 2009-05-04 12:13:39

2

正常字符串比較只適用於字典排序,而不適用於字符串的長度。

所以你必須編寫自己的功能,還需要檢查長度:

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 

我們在Monoid附近玩耍上週的大學,我們想出了這個可愛的替代Ord例如:

instance Ord a => Ord [a] where 
    compare = comparing length 
       `mappend` comparing head `mappend` comparing tail 

但是,如果你不很明白這一點,我建議你堅持使用第一個定義;-)

+2

比較長度的部分原因很有用,其他語言中的字符串的許多實現存儲或緩存字符串長度。好處是大多數字符串比較將花費時間O(1)作爲字符串長度的函數。 Haskell並非如此。作爲字符串長度的函數,所有與本機實現的字符串比較至少需要O(min(m,n))。 – yfeldblum 2009-05-04 11:35:30

+2

當然,這甚至不是最快的實現可能。只是我認爲提問者要求提供比較版本,在字典順序之前首先檢查字符串的長度。如果您想打印字符串列表並認爲先打印較小的字符串會更漂亮,這可能很有用。 – 2009-05-04 11:44:07

+0

@Tom:如果s2長於s1,我不確定您的小功能是否正常工作。例如,較小的「aa」「b」返回True。在我看來,OP希望函數在這種情況下返回False。 – 2009-05-04 12:09:02

7

該一個通溶液:

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 
4

以上由湯姆Lokhorst一個較短的版本的mappend版本:

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) 
相關問題