2009-05-04 49 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) 
相关问题