我想检查数字是否为素数。我编写了以下代码,但它没有返回任何值:
def isprime(x:Int) = {
| if (x==1) false
| else {
| for (i <- 2 to x-1) {
| if (x % i == 0) false
| else true
| }
| }
| }
答案 0 :(得分:6)
你所做的是一个叫做定义一个函数,所以显然它不会返回任何东西,事实上,这个函数会返回AnyVal,这显然对你没什么帮助。我怀疑你确实需要返回一个布尔类型。
由于您正在使用REPL,因此您需要定义函数以检查数字是否为素数。我把它称为isPrime2
,然后测试它。
def isPrime2(i :Int) : Boolean = {
| if (i <= 1)
| false
| else if (i == 2)
| true
| else
| !(2 to (i-1)).exists(x => i % x == 0)
| }
// isPrime2: (i: Int)Boolean
(1 to 10).foreach(i => if (isPrime2(i)) println("%d is prime.".format(i)))
// 2 is prime.
// 3 is prime.
// 5 is prime.
// 7 is prime.
如果你不在使用if else条件,我甚至会建议一个更简单的版本:
def isPrime1(n: Int): Boolean = ! ((2 until n-1) exists (n % _ == 0))
这也返回一个布尔值。
编辑:
正如@TheArchetypalPaul所述,这也暗示了,问题是你的for循环没有产生任何值 - 你计算一个真/假值,但后来不做任何事情。所以你的else子句不会产生任何值(事实上,它产生Unit
)。一旦找到除数,就需要返回false - 并且这样做的方式可能存在于isPrime1
中。
答案 1 :(得分:4)
单线解决方案
def isPrime(num:Int):Boolean =
(num > 1) && !(2 to scala.math.sqrt(num).toInt).exists(x =>num % x == 0)
答案 2 :(得分:2)
这是另一个班轮:
def isPrime(num: Int): Boolean = (2 to num) forall (x => num % x != 0)
forall
将检查谓词是否适用于此范围的所有元素
我刚刚意识到上面的代码对于更大的数字来说有点慢,所以这里有一个改进的版本:
def isPrime(n: Int): Boolean = (2 to math.sqrt(n).toInt) forall (x => n % x != 0)
答案 3 :(得分:1)
这可以是一种解决方案。
def isPrime(integer: Int): Boolean = {
if (integer == 1) false
else {
val domain = (2 to math.sqrt(integer).toInt).view
val range = domain filter (isDivisibleBy(integer, _))
range.isEmpty
}
}
def isDivisibleBy(integer: Int, divisor: Int): Boolean = integer % divisor == 0
现在回到您编写的代码,您的代码返回 AnyVal ,所需的返回类型应为布尔值。其背后的原因是Scala(或任何函数式语言)for循环是表达式而不是控制结构。
答案 4 :(得分:1)
这是另外一个解决方案:
def isPrime(n: Int) = Range(2, n-1).filter(i => n % i == 0).length == 0
甚至更短:
def isPrime(n: Int) = Range(2, n-1).filter(n % _ == 0).length == 0
答案 5 :(得分:1)
评论前面的答案(@jwvh除外):无需重复使用偶数。经过2的测试后,必须使用域3 to math.sqrt(integer).toInt by 2
。
我开发了一个加速的尾递归版本。它会跳过偶数个值,并一次性测试两个值。
import scala.annotation.tailrec
import scala.collection.immutable.TreeSet
import scala.compat.Platform
import scala.io.Source
object PrimesTestery extends App {
val oeisPrimes = TreeSet(oeisPrimesText.map(_.toInt): _*)
def rawText = Source.fromURL("https://oeis.org/A000040/a000040.txt")
def oeisPrimesText = rawText.getLines.takeWhile(_.nonEmpty).map(_.split(" ")(1)).toList
def isPrime(n: Long) = {
val end = math.sqrt(n).toInt
@tailrec
def inner(d: Int): Boolean = {
if (d > end) true
else if (n % d != 0 && n % (d + 2) != 0) inner(d + 6) else false
}
n > 1 && ((n & 1) != 0 || n == 2) && (n % 3 != 0 || n == 3) && inner(5)
}
println(s"Found ${oeisPrimes.size} primes on OEIS , last is ${oeisPrimes.last}.")
for (i <- (0 to oeisPrimes.last).par)
assert(isPrime(i) == oeisPrimes.contains(i), s"Wrong $i")
println(s"✔ Successfully completed without errors. [total ${Platform.currentTime - executionStart} ms]")
}
可以肯定的是,此代码针对素数和复合数字的素数列表进行了测试。
答案 6 :(得分:1)
该问题答案中的许多解决方案似乎要么行不通,要么没有涵盖明显的极端情况,要么公然效率低下。
下面是我的答案,该答案有效,涵盖了所有极端情况并且很有效,因为可能会出现在此特定领域中;也就是说,它会检查尽可能少的值,如果数字不是素数,则会尽早失败。
def isPrime(long: Long): Boolean =
if (long > 8L) {
!(((long % 2L) == 0L)
|| (3L to math.sqrt(long).toLong by 2L).exists(n => (long % n) == 0L))
} else
(long > 1L) && ((long == 2L) || ((long % 2L) != 0L))
答案 7 :(得分:1)
这一款不如一种衬垫优雅,但速度更快。它利用以下事实:所有质数(2和3除外)必须位于6k±1
处。因此,它将跳过可被2或3划分的测试数字。它将仅测试(5,7),(11,13),(17,19)等组。
def isPrime(number: Int): Boolean =
if (number < 4) number > 1
else if (number % 2 == 0 || number % 3 == 0) false
else (5 to math.sqrt(number).toInt by 6).forall(i => number % i != 0 && number % (i + 2) != 0)
答案 8 :(得分:0)
您还可以使用此递归函数:
med.out<- (med.fit, out.fit, treat="condition type", mediator = "shared oppression", robustSE = TRUE, sims = 100)
答案 9 :(得分:0)
这对于负数和大数也适用。 素数从2、3、5 ...
def isPrime(n: Int): Boolean = (n > 1) && ! Range(2, n-1).exists(n % _ == 0)
也
@tailrec
def isPrime(n: Int): Boolean = {
def isPrimeTailrec(divisor: Int): Boolean = {
if(divisor > Math.sqrt(Math.abs(n))) true
else n % divisor != 0 && isPrimeTailrec(divisor + 1)
}
if(n < 2) false
else isPrimeTailrec(2)
}
}
答案 10 :(得分:-1)
def primeNumber(范围:Int):单位= {
val primeNumbers: immutable.IndexedSeq[AnyVal] =
for (number :Int <- 2 to range) yield{
val isPrime = !Range(2, Math.sqrt(number).toInt).exists(x => number % x == 0)
if(isPrime) number
}
for(prime <- primeNumbers) println(prime)
}
答案 11 :(得分:-1)
def isPrime(n: Int) = (2 until n) forall(x => n % x !=0)