我必須生成一個小于給定數字的素數串列,然后找到所有加起來等于該值的生成素數對。
例如 num = 12
較小的素數 = 串列(3、5、7、11)
期望的結果:List((5, 7))
生成較小的素數串列沒有問題,但我不知道如何檢查哪些對滿足要求。這是我嘗試過的:
def check_sum(n: Int) =
val get_primes = (List.range(2, n)).filter(num => check_prime_bool(num)) // generating list of smaller prime numbers
val x = for {
a <- get_primes
b <- get_primes
if a b == n
} yield (a,b)
x
此解決方案有效,但我不能使用 for/yield 構造,我只能使用 map()、filter() 等函式。
uj5u.com熱心網友回復:
您已經實作的完全相同的實作,但使用 map, ... 將是:
def checkSum(n: Int) = {
val getPrimes = ((2 to n).filter(check_prime_bool)
getPrimes.flatMap { a =>
getPrimes.map(b => (a, b)).filter(b => a b == n)
}
}
像這樣,for理解中的第一個反向箭頭被編譯為:(getPrimes.flatMap { a => }您在for理解中將迭代變數命名為“a”)。for 理解的第二行被編譯成:(getPrimes.map { b => }注意變數“b”的名字,它和你傳遞的一樣)。"if" 被編譯成.withFilter方法,你可以用它filter來代替。
但是如果你愿意,我可以建議另一種實作,它是 tailrec 并且是 O(n) 而不是 O(n^2) (它不使用 map、flatMap、...,如果有人可以建議更好的實作這種方法,歡迎您編輯此答案):
import scala.annotation.tailrec
// assuming primes are sorted (since (2 to n).filter(isPrime) which you're using in this case, is sorted)
@tailrec
def checkSum(primes: Array[Int], acc: List[(Int, Int)] = List.empty, leftIndex: Int = 0, rightIndex: Int, num: Int): List[(Int, Int)] = {
if (leftIndex >= rightIndex) acc // pointers have reached each other, that's the end of the list
else {
val left = primes(leftIndex)
val right = primes(rightIndex)
val sum = left right
if (sum == num) checkSum(primes, (left -> right) : acc, leftIndex 1, rightIndex - 1, num)
else if (sum < num) { // move left pointer to right
checkSum(primes, acc, leftIndex 1, rightIndex, num)
} else { // move right pointer to left
checkSum(primes, acc, leftIndex, rightIndex - 1, num)
}
}
}
val primeNumbers = (2 to 12).filter(isPrime).toArray
checkSum(primeNumbers, rightIndex = primeNumbers.length - 1, num = 12)
// => List[(5, 7)]
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/475532.html
標籤:斯卡拉
