我一直试图通过做一些简单的问题来学习 haskell 。
问题所在
目前,我正在尝试实现一个函数primeFactorization :: Integer -> [(Integer, Integer)]
,以便输出一个元组列表,其中包含素数因子和它在数字中的幂。
示例输出
> primeFactorization 120
个[(2,3), (3,1), (5,1)]
自120以来= 2^3 * 3^1 * 5^1
我的(部分)解决方案
primeFactorization :: Integer -> [Integer]
primeFactorization n =
let
factors :: Integer -> [Integer]
factors n = [x | x <- [2..n-1], n `mod` x == 0]
isPrime :: Integer -> Bool
isPrime n
| n `elem` [0, 1] = False
| n == 2 = True
| n > 2 = null [ x | x <- [2..(ceiling . sqrt . fromIntegral) n], n `mod` x == 0]
| otherwise = False
in
filter isPrime $ (factors n)
这是一个有效的实现,可以得到一个数的素因子。但是,正如所看到的,它只输出素因子。我不知道如何在haskell中存储次数。而且,考虑到在haskell中迭代是不习惯的,我不知道如何实现这个解决方案。在python中,我会这样做:
def pf(number):
factors=[]
d=2
while(number>1):
while(number%d==0):
factors.append(d)
number=number/d
d+=1
return factors
于是,问题来了:如何实现素因子的幂?
注意事项:
1.我已经看到了:Prime factorization of a factorial然而,这并没有回答我的问题。
1.这不是家庭作业问题,我正在独立学习。
1条答案
按热度按时间mnemlml81#
你总是可以用递归来替换命令式语言循环(只要它们不干涉任何全局状态)。这可能不是最优雅的方法,但在这种情况下,用递归函数来模仿Python内部循环似乎是非常合适的:
(This你也可以用一个helper函数使它成为尾递归的,并在一个累加器变量上向前计数,但这会更尴尬,而且我认为在这种情况下没有内存/性能优势。)
你可以把它和你的Haskell代码一起使用(对于您已经找到的每一个因素,检查它发生的频率),或者扩展它,使整个过程像Python解决方案一样工作(这实际上更有效,因为它避免了对每一个数都检查它是否是素数)。为此,您只需要给予结果中的最终值
n
。让's使用where
块来处理模式匹配,并且还使rem
和:那么Python代码的等价物是
这实际上像在Python中一样,给出了一个也包括非分隔符(幂为0)的列表。