Haskell - 使用list comprehension返回包含数字的整数

时间:2015-10-06 09:28:42

标签: haskell list-comprehension

对于作业,我被要求使用列表理解重写以下函数。此函数接受整数列表和整数数字a,并返回列表中包含数字a的整数数。

e.g。

count [102,41,256] 2 

应该返回2

count [98,4,376] 2

应该返回0

这就是我对非列表理解函数所具有的:

split :: Int -> [Int]
split 0 = []
split x = split (div x 10) ++ [rem x 10]

checkDigits :: [Int] -> Int -> Int
checkDigits [] y = 0
checkDigits (x:xs) y
    | x == y = 1 + (checkDigits xs y)
    | otherwise = checkDigits xs y

count :: [Int] -> Int -> Int
count [] a = 0
count (x:xs) a 
    | (checkDigits (split x) a) > 0 = (checkDigits (split x) a) + (count xs a) 
    | otherwise = count xs a

Split将接受一个整数并返回列表中的整数

split 321    will return:    [3,2,1]

checkDigits计算一个数字出现在整数中的次数(这是为了解决count [22] 2返回0时应返回的错误2

e.g. the digit '2' appears 4 times in the list [2,65,42,22]

最后在计数中,我们使用checkDigits检查x中的任何数字是否等于a,如果此数字大于0(1或更多等于a )然后添加找到的位数并再次调用。

我是列表理解的新手,如果列表中的数字等于a,我只能设法让它工作:

countD :: [Int] -> Int -> Int
countD intL a = length [y | y <- intL, y == a]

此处countD [2,3,4,22] 2返回1我如何更改我的内容,以便它返回3(因为有2个列表)。

3 个答案:

答案 0 :(得分:5)

我能做的最好。 如果有人向我展示如何将整数2数字作为参数传递而不是硬编码,我会感激。

感谢Erik的回答。

countDigits :: [Int] -> Int -> Int
countDigits xs d = sum [1 | n <- (concat . map show) xs, n == d']
    where d':[] = show d

答案 1 :(得分:3)

checkDigits中使用splitcountD。这是计算包含数字的整数的数量(在您的示例中为两个):

countD intL a = length [y | y <- intL, (checkDigits (split y) a) > 0]

以下是数字出现的总次数(在您的示例中为三个):

countD intL a = sum [checkDigits (split y) a | y <- intL]

答案 2 :(得分:3)

你的问题对count函数应该准确做什么不明确。一开始你说

  

列表中包含数字

的整数数

而后来你说

  

count [22] 2 /.../应该返回2

2中包含数字[22]的整数数 - 该列表中只有一个整数,所以你应该返回1,不管这个整数包含数字2两次的事实。

因此,我已经为下面两种可能性提供了解决方案。

对于第一种可能性,这个解决方案是我能想到的最短的解决方案:

-- these are optional
type Digit  = Int
type Number = Int
type Count  = Int

count :: [Number] -> Digit -> Count
count xs d = sum [count' x | x <- xs]  -- same as `sum $ map count' xs`
  where count' x = if d' `elem` show x then 1 else 0
        d':[] = show d

但是,如果第二种可能性确实正确并且count [22] 2应该返回2,那么相应地更改count'辅助函数:

count :: [Number] -> Digit -> Count
count xs d = sum [count' x | x <- xs]
  where count' i = length $ filter (== d') (show i)
        d':[] = show d