问题描述
|
这段代码对我来说似乎有点令人困惑。有人在乎通过解释帮助我吗?
uniq_c l = [ nl (tam l) i s | (s,i) <- uniq_c\' l]
tam = maximum . map snd . uniq_c\'
uniq_c\' [] = []
uniq_c\' (h:t) = let (list,rest) = span (==h) t
n = length list + 1
in (h,n) : uniq_c\' rest
nl tam n line = let l = length $ show n
l_tam = length $ show tam
n\' = replicate (l_tam-l) \" \"
in concat n\' ++ show n ++ \" \" ++ line
解决方法
uniq_c
提供一个字符串出现在一个字符串列表中的次数的计数,该字符串列表中包含一个与特定字符串的空格:
*A> uniq_c [\"The\",\"quick\",\"brown\",\"fox\",\"fox\"]
[\"1 The\",\"1 quick\",\"1 brown\",\"2 fox\"]
*A> uniq_c $ [\"The\",\"fox\"] ++ (replicate 100 \"fox\")
[\" 1 The\",\" 1 quick\",\" 1 brown\",\"103 fox\"]
uniq_c\'
提供(string,count)
的元组列表。
tam
查找最大的计数(这将是任何特定字符串的最后一次出现)。
nl
将计数缩进,以便使计数正确对正。
*A> mapM_ putStrLn $ uniq_c $ [\"The\",\"fox\"] ++ (replicate 100 \"fox\")
1 The
1 quick
1 brown
103 fox
, 该代码不是很好。它不会重用任何现有的Haskell库。
这是另一种选择。 group
功能可完成工作;识别重复出现的情况。 length &&& head
取每个这样的子列表并进行计数和单词。最后,uniq_c
找到最大宽度,并使用printf
格式化输出。
import Control.Arrow
import Data.List
import Text.Printf
uniq :: (Eq a) => [a] -> [(Int,a)]
uniq = map (length &&& head) . group
uniq_c :: [String] -> [String]
uniq_c l =
let us = uniq l
width = length . show . maximum . map fst $ us
in map (uncurry $ printf \"%*d %s\" width) us