求编写Haskell factors函数:输入Int列表输出各数因数列表
解决Haskell的因数列表生成问题
嘿,作为Haskell新手,能想到用map、filter这些工具已经很棒了!我们一步步来搞定这个factors函数。
首先看你的需求:输入一个Int列表,输出每个元素对应的严格介于1和自身之间的因数组成的列表(从例子里的[2,5,7,8]输出[[],[],[],[2,4]]就能看出来,我们要排除1和数字本身)。
第一步:先写单个数字的因数生成函数
我们先实现一个辅助函数,给定一个整数n,返回它的目标因数列表。用列表推导式最直观:
getTrueFactors :: Int -> [Int] getTrueFactors n = [x | x <- [2..n-1], n `mod` x == 0]
解释一下这个列表推导式:
[2..n-1]:生成从2到n-1的所有整数(因为我们要排除1和n自己)nmodx == 0:筛选出能整除n的数(也就是n除以x余数为0)
测试一下这个函数:
getTrueFactors 2→[2..1]是空列表,输出[]getTrueFactors 8→ 筛选出2和4,输出[2,4],完全符合你的例子!
第二步:用map批量处理列表
现在我们有了处理单个数字的函数,只需要用map把它应用到输入列表的每个元素上,就得到了最终的factors函数:
factors :: [Int] -> [[Int]] factors xs = map getTrueFactors xs
或者你也可以把两个函数合并成一行,用匿名函数简化:
factors :: [Int] -> [[Int]] factors xs = map (\n -> [x | x <- [2..n-1], n `mod` x == 0]) xs
验证你的例子
把输入[2,5,7,8]代入:
factors [2,5,7,8] -- 等价于 map getTrueFactors [2,5,7,8] -- 结果就是 [[],[],[],[2,4]]
完美匹配你要的输出!
额外小提示(可选)
如果之后你想扩展需求,比如包含1作为因数,只需要把列表推导式的起始值改成1:
getFactorsWithOne n = [x | x <- [1..n-1], n `mod` x == 0]
另外,对于大数来说,遍历到n-1效率不高,可以优化成遍历到sqrt(n),然后收集对应的配对因数,不过对于新手来说,先掌握基础的实现就足够啦。
内容的提问来源于stack exchange,提问作者Alutri
相关产品推荐
相关产品推荐

