Get list of primes to N

自古美人都是妖i 提交于 2021-02-20 19:13:09

问题


I'm trying to write a function which takes an Int and returns all of the prime numbers up to and including that Int.

for example "list of primes for 8" = List(3,5,7)

This is what I have so far :

  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) = {

    }

for the function getListOfPrimesToN I plan to 1. create a List "l" of size n and populate it with elements ranging from 0 to n. 2. call map function of "l" and call isPrime for each element in List.

How to create the List of element 1 to N ?

Any alternative solutions for returning all of the prime numbers up to and including an Int N welcome.


回答1:


You can solve this with infinite streams. If you had a stream primes of all the primes, you could just say primes.takeWhile(_ <= n) to get the primes up to and including n.

To get all the primes, you start with a stream of all the numbers starting from 2, the first prime. You can then skip all the even numbers since those are definitely not prime. Then you can skip all the other numbers that are not prime.

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

Now you just need isPrime to check if a given number is prime. A number is prime if it is not divisible by any smaller prime. We actually need only consider primes whose square is not greater than the number (since, logically, a composite number's smallest prime factor can't be larger than its square root).

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

Check this in the REPL:

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

Caveat: This only works for positive numbers smaller than Integer.MAX_VALUE.




回答2:


An implementation of the Sieve of Eratosthenes algorithm for efficiently finding prime numbers up to a given value N includes the following, (fixed and improved on this SO answer),

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
  }
} 

Hence

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

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

Note Find prime numbers using Scala. Help me to improve for additional ideas and discussion.




回答3:


Here is the code based on your:

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)

Here is another solution using 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)



回答4:


How about this.

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
}


来源:https://stackoverflow.com/questions/26287604/get-list-of-primes-to-n

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!