获取N的素数列表

时间:2014-10-09 20:43:43

标签: scala primes

我尝试编写一个函数,该函数接受一个I​​nt并返回所有素数,包括该Int。

例如" 8"的素数列表=列表(3,5,7)

这是我到目前为止所做的:

  def isPrime(i: Int): Boolean = {
    if (i <= 1)
      false
    else if (i == 2)
      true
    else
      !(2 to (i - 1)).exists(x => i % x == 0)
  }                                               //> isPrime: (i: Int)Boolean

    def getListOfPrimesToN(n : Int) = {

    }

对于我计划的函数getListOfPrimesToN 1.创建一个List&#34; l&#34;大小为n,并使用0到n之间的元素填充它。 2.呼叫地图功能&#34; l&#34;并为List中的每个元素调用isPrime。

如何将元素1的列表创建为N?

用于返回所有素数的任何替代解决方案,包括Int N welcome。

4 个答案:

答案 0 :(得分:4)

您可以使用无限流来解决此问题。如果你有所有素数的流primes,你可以说primes.takeWhile(_ <= n)来获得素数,包括n

要获得所有素数,您可以从2开始的所有数字流开始,即第一个素数。然后你可以跳过所有偶数,因为那些绝对不是素数。然后你可以跳过所有其他不是素数的数字。

val primes = 2 #:: Stream.from(3,2).filter(isPrime)

现在您只需要isPrime来检查给定的数字是否为素数。如果数字不能被任何较小的素数整除,则该数字是素数。我们实际上只需要考虑其平方不大于数字的素数(因为,逻辑上,复合数的最小素数不能大于其平方根)。

def isPrime(n: Int): Boolean =
  primes.takeWhile(p => p*p <= n).forall(n % _ != 0)

在REPL中检查:

scala> primes.takeWhile(_ <= 8).toList
res0: List[Int] = List(2, 3, 5, 7)

警告:这仅适用于小于Integer.MAX_VALUE的正数。

答案 1 :(得分:3)

Sieve of Eratosthenes算法的实现,用于有效地查找达到给定值N的素数,包括以下内容,(this SO答案修正和改进),

implicit class Sieve(val N: Int) extends AnyVal {
  def primesUpTo() = {
    val isPrime = collection.mutable.BitSet(2 to N: _*) -- (4 to N by 2)
    for (p <- 2 +: (3 to Math.sqrt(N).toInt by 2) if isPrime(p)) {
      isPrime --= p*p to N by p
    }
    isPrime.toImmutable
  }
} 

因此

10.primesUpTo.toList
res: List(2, 3, 5, 7)

11.primesUpTo.toList
res: List(2, 3, 5, 7, 11)

请注意Find prime numbers using Scala. Help me to improve以获取更多想法和讨论。

答案 2 :(得分:0)

以下是基于您的代码:

scala> def isPrime(n: Int): Boolean =
     |   n >= 2 && (2 to math.sqrt(n).toInt).forall(n%_ != 0)
isPrime: (n: Int)Boolean

scala> def getListOfPrimesToN(n: Int): List[Int] = 
     |   List.range(2, n+1) filter isPrime
getListOfPrimesTON: (n: Int)List[Int]

scala> getListOfPrimesToN(97)
res0: List[Int] = List(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97)

以下是使用Stream的另一种解决方案:

scala> def getListOfPrimesToN(n: Int): List[Int] = {
     |   lazy val ps: Stream[Int] = 2 #:: Stream.from(3)
                 .filter(x => ps.takeWhile(p => p*p <= x).forall(x%_ != 0))
     |   ps.takeWhile(_ <= n).toList
     | }
getListOfPrimesToN: (n: Int)List[Int]

scala> getListOfPrimesToN(97)
res0: List[Int] = List(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97)

答案 3 :(得分:0)

这个怎么样。

def getPrimeUnder(n: Int) = {
  require(n >= 2)
  val ol = 3 to n by 2 toList // oddList
  def pn(ol: List[Int], pl: List[Int]): List[Int] = ol match {
    case Nil => pl
    case _ if pl.exists(ol.head % _ == 0) => pn(ol.tail, pl)
    case _ => pn(ol.tail, ol.head :: pl)
  }
  pn(ol, List(2)).reverse
}