对列表进行快速排序并将其转换为元组列表(elem,count)



如何将未排序的单词列表转换为元组列表(单词,计数),按单词排序(fst)最小-最大大小写不区分?

["AAA","America", "England", "Spain"," Ireland"," aeroplane",
 "aeroplane", "Aeroplane", "AeRoPlAne", "helicopter", "HELICOPTER",
 "Zebra", "America", "Elephant", "abc", "A.B.C." , "haskell", "Haskell", "ZZZ", "zzz"]

预期产出:

[("a.b.c.",1),("aaa",1),("abc",1),("aeroplane",4),("america",2),("elephant",1)
,("england",1),("haskell",2),("helicopter",2),("ireland",1),("spain",1),("zebra",1),("zzz",2)]
[("a.b.c",1), ("zzz", 2)]

我已将其分解为步骤,这些步骤应该更容易掌握。首先,对列表进行排序,然后将其缩减为(Word,计数)元组列表。

import Data.Char (toLower)
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []  
quicksort (x:xs) =
  (quicksort [a|a<-xs, a<=x]) ++ [x] ++ (quicksort [a|a<-xs, a>x])
addCount :: String -> [(String, Int)] -> [(String, Int)]
addCount a [] = [(a, 1)]
addCount a (x:xs)
  | a == fst x = (fst x, (snd x) + 1) : xs
  | otherwise  = x : (addCount a xs)
occurrences :: [(String, Int)] -> [String] -> [(String, Int)]
occurrences counts [] = counts
occurrences counts (x:xs) =
  occurrences countL xs
  where countL = addCount x counts
myList = ["AAA","America", "England", "Spain","Ireland", "aeroplane",
          "aeroplane", "Aeroplane", "AeRoPlAne", "helicopter", "HELICOPTER",
          "Zebra", "America", "Elephant", "abc", "A.B.C." , "haskell", "Haskell",
          "ZZZ", "zzz"]
main = do
  let downcased = map (map toLower) myList
  let sorted = quicksort downcased
  let occurencesL = occurrences [] sorted
  putStrLn . show $ occurencesL
  putStrLn . show $ [head occurencesL, last occurencesL]

非常冗长,但我希望您能更轻松地理解这种方式发生的事情。

一个较短方法的示例:

  import Data.Char (toLower)
  import Data.List
  main = do
    let l = map (a -> (head a, length a)) $ groupBy (x y -> (map toLower x) == (map toLower y)) myList
    putStrLn . show $ l
    putStrLn . show $ [head l, last l]

这是一个单行:

    Data.List.sort $ Data.Map.toList $ Data.Map.fromListWith (+) [(map Data.Char.toLower word, 1) | word <- lst]

分组功能:

myGroup :: [[Char]] -> [([Char],Int)]
myGroup = fmap (x -> (head x,length x)) . groupBy (==) . sort . fmap (fmap toLower . filter (not . isSpace))

请注意,我假设您要从字符串中删除空格。您可以通过更改过滤器轻松更改该部分。

然后边界函数:

headLast :: [t] -> [t]
headLast xs = [head xs,last xs]

最新更新