使用列表理解 return 个包含数字的整数

Use list comprehension to return number of integers which contain a digit

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

的整数数量

例如

count [102,41,256] 2 

应该return2

count [98,4,376] 2

应该return0

这是我对非列表理解功能的看法:

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

拆分将接受一个整数和 return 列表中的整数

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

checkDigits 计算一个数字出现在整数中的次数(这是为了解决 count [22] 2 会 return 为 0 而应该出现的错误return 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 returns 1l 我如何改变我所拥有的,以便它 return 3(因为有 3 2在列表中)。

countD中使用checkDigitssplit。这就是计算包含数字的整数数量的方法(在您的示例中为两个):

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

下面是计算数字出现的总次数(在您的示例中为 3 次)的方法:

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

关于 count 函数究竟应该做什么,您的问题不明确。一开始你说

the number of integers in the list which contain the digit

而你稍后会说

count [22] 2 /.../ should return 2

而不是 [22] 中包含数字 2 的整数的数量——该列表中只有一个整数,所以你应该return 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 应该 return 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

尽我所能。 如果有人告诉我如何将整数 2 数字作为参数传递而不是硬编码,我将不胜感激

感谢埃里克的回答。

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