问题描述
我正在尝试在Scala中编写一个递归函数,该函数需要一个正整数并打印出其主要因子。例如200 = 2、2、2、5、5。这是我编写的代码。
println(calculatePrimeFactors(200,2))
def isPrime( x:Int ):Boolean = {
def recIsP( n:Int,i:Int ) : Boolean = (i == n) || (n % i != 0) && recIsP(n,i + 1)
recIsP(x,2)
}
def calculatePrimeFactors(n:Int,i:Int):String= {
if (i==n) {
""
}else if(isPrime(i) && n%i==0){
i.toString + "," + calculatePrimeFactors(n,i+1)
}else{
calculatePrimeFactors(n,i+1)
}
}
如何做到这一点,以便代码正确运行并输出2,2,5,.
,我尝试使用带有此语句n = n / i
的循环,但是Scala返回错误,提示无法完成对val的重新分配
解决方法
好吧,您可以调试代码,然后看到通过数字后就不会再打印了。
要打印所有素数,您需要将找到的素数除以,然后从除数重新开始。请考虑为calculatePrimeFactors
植入以下代码:
def calculatePrimeFactors(n:Int,i:Int):String= {
if (i==n) {
i.toString
} else if(n%i==0) {
i.toString + "," + calculatePrimeFactors(n/i,i)
} else {
calculatePrimeFactors(n,i+1)
}
}
现在您将获得输出:2,2,5,5
。可以在Scastie找到代码运行。
此算法的干净版本可能如下所示:
def calculatePrimeFactors(n: Int): List[Int] = {
def loop(p: Int,rem: Int,res: List[Int]): List[Int] =
if (rem % p == 0) {
loop(p,rem / p,res :+ p)
} else if (p > rem) {
res
} else {
loop(p + 1,rem,res)
}
loop(2,n,Nil)
}
根据需要使用mkString(",")
将结果转换为String
。
请注意,由于任何非素数除数都会有较小的素因数,因此无需检查除数是否为素数。