我正在尝试在 Haskell 中编写一个函数来计算给定数字的所有因子,除了它本身。
结果应该是这样的:
factorlist 15 => [1,3,5]
Run Code Online (Sandbox Code Playgroud)
我是 Haskell 和整个递归主题的新手,我很确定我应该在这个例子中应用它,但我不知道在哪里或如何应用。
我的想法是将给定的数字与从 1 到 n div2的列表的第一个元素与mod函数进行比较,但以某种方式递归地进行比较,如果结果是,0则将数字添加到新列表中。(我希望这是有道理的)
我将不胜感激在这件事上的任何帮助
到目前为止,这是我的代码:(它不起作用..但以某种方式说明了我的想法)
factorList :: Int -> [Int]
factorList n |n `mod` head [1..n`div`2] == 0 = x:[]
Run Code Online (Sandbox Code Playgroud)
有几种方法可以处理这个问题。但首先,让我们写一个小帮手:
isFactorOf :: Integral a => a -> a -> Bool
isFactorOf x n = n `mod` x == 0
Run Code Online (Sandbox Code Playgroud)
这样我们就可以编写12 `isFactorOf` 24并获得True或False。对于递归部分,假设我们使用一个带有两个参数的函数:一个是我们想要分解的数字,第二个是我们当前正在测试的因子。我们只测试小于或等于 的因子n `div` 2,这导致:
createList n f | f <= n `div` 2 = if f `isFactorOf` n
then f : next
else next
| otherwise = []
where next = createList n (f + 1)
Run Code Online (Sandbox Code Playgroud)
因此,如果第二个参数是 的因子n,我们将其添加到列表中并继续,否则我们就继续。我们只在f <= n `div` 2. 现在为了 create factorList,我们可以简单地使用createList足够的第二个参数:
factorList n = createList n 1
Run Code Online (Sandbox Code Playgroud)
递归隐藏在createList. 因此,createList是一个工人,你可以把它隐藏在where里面factorList。
请注意,可以factorList使用过滤器或列表推导式轻松定义:
factorList' n = filter (`isFactorOf` n) [1 .. n `div` 2]
factorList'' n = [ x | x <- [1 .. n`div` 2], x `isFactorOf` n]
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,您不会自己编写递归。
filter功能。