免责声明:我是Haskell的新手,我不记得很多关于大学的FP,所以我的代码可能会有一两个以上的错误。这也是我的欧拉问题3的代码。
我试图递归调用一个函数,其中两个数组作为参数,一个数组作为结果。
目标:
这是我的代码:
mkList :: Int -> [Int]
mkList n = [1..n-1]
modArray :: Int -> Int -> [Int]
modArray a b = [ x*b | x <- [1..a], x `mod` b == 0]
modArrayAll :: [Int] -> [Int] -> [Int]
modArrayAll [] [] = []
modArrayAll (x:xs) (y:ys) = (e)
where
m = head( ys)
n = length( xs)
e = (modArrayAll xs ys ) \\ modArray n m
(主要)
let allNumbers = mkList (first + 1)
let allFactors = mkList (first + 1)
let mainList2 = modArrayAll allNumbers allFactors
这会产生一个空列表。但是,如果我有:
e = xs \\ modArray n m --WORKS for one iteration
我从1到10得到所有奇数。
我的问题:为什么这不按照我期望的方式工作?我希望递归堆栈会达到空数组条件并返回一个空数组,该数组不会从调用数组中删除,它会继续只返回素数?
答案 0 :(得分:5)
我复制了您的目标说明:
-- assume n is 10 for this question
n=10
-- create a list of all natural numbers from 1 to n (variable is 'allNumbers' is code)
allNumbers = [1..n]
-- create another list of all natural numbers from 1 to n (variable is 'allFactors' is code)
allFactors = [2..n] -- i suspect you really wanted this rather than [1..n]
-- take the first element in 'allFactors' and
-- multiply the rest of the numbers of 'allFactors' by this number.
-- (this generates an array of numbers)
-- continue from 1 to n until 'allFactors' is empty
factorProducts = [ x*y | x <- allFactors, y <- allFactors]
-- remove all these numbers from 'allNumbers'
whatYouWanted = allNumbers \\ factorProducts
此刻,你似乎还在思考一种相当强制性的思维模式。尝试更多地考虑你想要的东西,而不是如何得到它:)
答案 1 :(得分:1)
modArray n m
创建一个m
的倍数列表,然后将其从整数的“主列表”中删除。但modArray n m
包含1*m
,因此每个号码都会被移除,因为它本身就是“倍数”。在您的测试用例中,您只得到奇数,而您希望2仍然在结果列表中。此外,1还包含在您的因子列表中,这将消除所有数字,因为它们都是1的倍数。
递归的终止案例是modArrayAll [] [] = []
,因此返回一个空列表。然后在周围的递归调用中,此处使用此返回值:
(modArrayAll xs ys) \\ modArray n m
这会尝试从modArray n m
返回的已空列表中删除其他元素(modArrayAll xs ys
返回的元素)。不会在任何地方添加新元素,结果列表将保持为空。使用您的算法,您希望[]
- case返回整个数字列表,而不是空数字。然后周围递归函数调用中的\\ modArray n m
可以过滤掉越来越多的非素因子。