﻿ 有效地检查(大)列表的所有元素是否相同 - 代码日志

#### 有效地检查(大)列表的所有元素是否相同

``````allTheSame :: (Eq a) => [a] -> Bool
allTheSame xs = and \$ map (== head xs) (tail xs)
``````

``````allTheSame' :: (Eq a) => [a] -> Bool
allTheSame' xs = (length xs) == (length \$ takeWhile (== head xs) xs)
``````

``````allTheSame'' :: (Eq a) => [a] -> Bool
allTheSame'' xs
| n == 0 = False
| n == 1 = True
| n == 2 = xs !! 0 == xs !! 1
| otherwise = (xs !! 0 == xs !! 1) && (allTheSame'' \$ snd \$ splitAt 2 xs)
where  n = length xs
``````

``````allTheSame''' :: (Eq a) => [a] -> Bool
allTheSame''' xs
| n == 0 = False
| n == 1 = True
| n == 2 = xs !! 0 == xs !! 1
| n == 3 = xs !! 0 == xs !! 1 && xs !! 1 == xs !! 2
| otherwise = allTheSame''' (fst split) && allTheSame''' (snd split)
where n = length xs
split = splitAt (n `div` 2) xs
``````

``````allTheSame'''' :: (Eq a) => [a] -> Bool
allTheSame'''' xs = all (== head xs) (tail xs)
``````

>我认为解决方案0不是非常有效率，至少在内存方面，因为地图将在应用之前构造另一个列表和其元素。我对吗？
>解决方案1仍然不是非常有效率，至少在内存方面，因为takeWhile将再次创建一个附加列表。我对吗？
>解决方案2是尾递归(右？)，它应该是非常有效的，因为它将返回False，一旦(xs !! 0 == xs !! 1)为False。我对吗？
>解决方案3应该是最好的，因为它的复杂度应该是O(log n)

``````ghci> and \$ map (< 1000) [1..]
False
``````

``````and [] = True
and (x:xs) = x && and xs

map f [] = []
map f (x:xs) = f x : map f xs

True && x = x
False && x = False
``````

``````allTheSame [7,7,7,7,8,7,7,7]
allTheSame (7:7:7:7:8:7:7:7:[])
and \$ map (== head (7:7:7:7:8:7:7:7:[])) (tail (7:7:7:7:8:7:7:7:[]))
and \$ map (== 7)  (tail (7:7:7:7:8:7:7:7:[]))
and \$ map (== 7)          (7:7:7:8:7:7:7:[])
and \$ (== 7) 7 : map (== 7) (7:7:8:7:7:7:[])
(== 7) 7 && and (map (== 7) (7:7:8:7:7:7:[]))
True     && and (map (== 7) (7:7:8:7:7:7:[]))
and (map (== 7) (7:7:8:7:7:7:[]))
(== 7) 7 && and (map (== 7)   (7:8:7:7:7:[]))
True     && and (map (== 7)   (7:8:7:7:7:[]))
and (map (== 7)   (7:8:7:7:7:[]))
(== 7) 7 && and (map (== 7)     (8:7:7:7:[]))
True     && and (map (== 7)     (8:7:7:7:[]))
and (map (== 7)     (8:7:7:7:[]))
(== 7) 8 && and (map (== 7)       (7:7:7:[]))
False    && and (map (== 7)       (7:7:7:[]))
False
``````

http://stackoverflow.com/questions/6121256/efficiently-checking-that-all-the-elements-of-a-big-list-are-the-same