使用列表理解 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 1
l 我如何改变我所拥有的,以便它 return 3
(因为有 3 2
在列表中)。
在countD
中使用checkDigits
和split
。这就是计算包含数字的整数数量的方法(在您的示例中为两个):
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
对于一项作业,我被要求使用列表理解重写以下函数。此函数接受整数列表和整数数字 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 1
l 我如何改变我所拥有的,以便它 return 3
(因为有 3 2
在列表中)。
在countD
中使用checkDigits
和split
。这就是计算包含数字的整数数量的方法(在您的示例中为两个):
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