【问题标题】:Determining if a given number is a prime in haskell确定给定数字是否是haskell中的素数
【发布时间】:2011-06-09 02:41:34
【问题描述】:

所以我设计了以下函数来查看给定数字是否是 Haskell 中的素数(它假设第一个素数是 2):

isPrime k = length [ x | x <- [2..k], k `mod` x == 0] == 1

即使它可以被多个数字整除,它也存在继续评估的明显缺陷:(。当它找到多个解决方案时,是否有任何理智方法可以“削减”评估,使用列表推导式?

另外,您还会尝试哪些其他实现?我不是在这里寻找性能,我只是想看看是否还有其他更“haskellish”的方式来做同样的事情。

【问题讨论】:

标签: algorithm haskell primes primality-test


【解决方案1】:

对代码进行“短路”评估并依赖于 Haskell 列表的惰性的快速更改是:

isPrime k = if k > 1 then null [ x | x <- [2..k - 1], k `mod` x == 0] else False

k 的第一个除数将导致列表非空,null 的 Haskell 实现将只查看列表的第一个元素。

您应该只需要检查 sqrt(k) 然而:

isPrime k = if k > 1 then null [ x | x <- [2..isqrt k], k `mod` x == 0] else False

当然,如果您希望进行高性能素性测试,则首选库。

【讨论】:

  • @Can 你的编辑破坏了这篇文章。请不要那样做。
  • @JamesKPolk 感谢您拒绝对这篇文章进行无意义的编辑。 :)
  • @WillNess 我重新检查了我的编辑。再一次,我看不出它与原始答案有何不同。保留原作者的所有信息。正如我的编辑说明所述,这只是一个小的格式编辑,修复了一些措辞和样式。
  • @WillNess 这对你来说可能是荒谬的,但它不适合我,当然也不适合其他人,因为它也得到了另外两个人的批准。一直以来,我都会在 SE 上编辑帖子以使它们更具可读性和平易近人;他们得到批准。我所做的这些更改对您来说似乎毫无意义,但它们确实很重要。学习是至关重要的,信息应该尽可能地呈现出来。
  • @Can “又一次”(?这是我所知道的我们的第一次交流。)您破坏了两件事:1.您将 isqrt 更改为 sqrt,这不适用于 Integral 类型,所以代码会导致错误。 2. 你将“relies”改为“rely”,这破坏了句子的意思(有点微妙,但仍然是真实的感觉)。
【解决方案2】:

这里是haskell.org 中prime numbers in haskell 的最佳资源

这里是prime.hsgithub 项目

【讨论】:

    【解决方案3】:

    这可能并不直接相关,但关于在函数式语言中寻找素数的话题,我发现 Melissa E. O'Neill 的 The Genuine Sieve of Eratosthenes 非常有趣。

    【讨论】:

      【解决方案4】:

      我喜欢这种方法:

      首先make函数得到n的所有因数:

      factors n = [x | x <- [1..n], mod n x == 0]
      

      然后检查因子是否只是给定的数字和1,如果是,则该数字是素数:

      prime n = factors n == [1,n]
      

      【讨论】:

        【解决方案5】:

        忽略素数问题,专注于length xs == n的更有效方法的窄点:

        hasLength :: Integral count => [a] -> count -> Bool
        _        `hasLength` n | n < 0 = False
        []       `hasLength` n         = n == 0
        (_ : xs) `hasLength` n         = xs `hasLength` (pred n)
        
        isPrime k = [ x | x <- [2..k], k `mod` x == 0)] `hasLength` 1
        

        【讨论】:

          【解决方案6】:

          这可能是愚蠢和低效的(我是一个完整的 Haskell 新手),但函数 isMyNumberPrime(在 ghci 中)似乎告诉你一个数字是否是素数。

          factors n = [x | x <- [2..(n`div` 2)], mod n x == 0]
          factormap n = fmap factors $ factors n
          isMyNumberPrime n = case factormap n of [] -> True; _ -> False
          

          【讨论】:

            猜你喜欢
            • 2016-09-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-06-05
            • 1970-01-01
            • 2015-01-22
            相关资源
            最近更新 更多