swift 中的第 n 个素数

nth prime number in swift

我试图在 xCode 的 Swift 中找到第 n 个质数,但我似乎无法正常工作,它只是给出了一个质数列表。

func nthPrimeNumber (n: Int) -> Int
{
    var prime: Int
    var divisor: Int
    var isPrime: Bool
    for (prime = 2;  prime <= 50;  ++prime )
    {
        isPrime = true;
        for (divisor = 2;  divisor < prime;  ++divisor )
        {
            if ((prime % divisor) == 0 )
            {
                isPrime = false
            }
        }
        if (isPrime == true )
        {
            println(" \(prime)")
        }
    }

    return prime
}

对您的代码进行最少的更改,但是,正如评论者所说,添加终止逻辑:

func nthPrimeNumber(n: Int) -> Int {
    var prime: Int
    var divisor: Int
    var isPrime: Bool
    var counter = 0
    for (prime = 2;  prime <= 50 && counter < n;  ++prime )
    {
        isPrime = true;
        for (divisor = 2;  divisor < prime;  ++divisor )
        {
            if ((prime % divisor) == 0 )
            {
                isPrime = false
            }
        }
        if (isPrime)
        {
            counter++
        }
    }

    return prime-1
}

[注:此代码returns为nth素数,按要求;不只是 50 或 51,都是非素数。]

您指定为参数的 n 将被完全忽略,因此当 prime 变为 51 时您的计算将终止。 50 下的所有素数都被打印出来,并返回巧合的 51。如果你想要第 n 个素数,你需要 a) 计算遇到的素数 b) 当你得到第 n 个时停止。

您还有一个问题要处理“我想要第 20 个素数,但我只是在寻找 50 以下的素数”- 可能没有素数。

并且,您使用 divisor < prime 执行 prime % divisor,但该除数永远不需要超过 prime/2

所有这些加上风格的改进导致:

func nthPrimeNumber (var n: Int) -> Int
{
  if n < 1 { return 0 } // error condition

  var prime = 2

  while (true) { // find the `nth` no matter how large `prime`

    var isPrime = true
    for (var divisor = 2; divisor <= prime/2; ++divisor) {
      if 0 == prime % divisor { isPrime = false; break }
    }

    if isPrime {
      println (" \(prime)")
      if 0 == --n { return prime }
    }

    prime++
  }
}

和一些结果:

 39> nthPrimeNumber(1)
 2
$R7: (Int) = 2
 40> nthPrimeNumber(3)
 2
 3
 5
$R8: (Int) = 5
 41> nthPrimeNumber(10)
 2
 3
 5
 7
 11
 13
 17
 19
 23
 29
$R9: (Int) = 29

我鼓励您尝试 1000 中的 n

extension FixedWidthInteger {
    var isPrime: Bool {
        if self <  2 { return false }
        let squareRoot = Self(Double(self).squareRoot())
        if squareRoot * squareRoot == self { return false }
        for i in 2..<Self(Double(self).squareRoot().rounded(.up)) where self % i == 0 {
           return false
        }
        return true
    }
}

let twoDigitsPrimeNumbers = (1..<100).filter { [=11=].isPrime }
print(twoDigitsPrimeNumbers)  // [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]

func nthPrime(nth: Int)-> Int {
    var primeCounter = 0
    var number = 2
    while true {
        if number.isPrime {
            primeCounter += 1
            if nth == primeCounter { return number }
        }
        number += 1
    }
}
nthPrime(1000)   // 7,919
func isNumberDivisible(_ number: Int, by divisor: Int) -> Bool {
    number % divisor == 0
}

func isPrime(_ number: Int) -> Bool {
    
    var result: Bool = true
    
    for divisor in stride(from: 2, to: number, by: 1) {
        if isNumberDivisible(number, by: divisor) {
            result = false
        }
    }
    return result
}

for i in 0...100 { // you can choose whatever number you want
    if i == 0 || i == 1 {
        print("\(i) is not a prime number")
    } else if isPrime(i){
        print("\(i) is a prime number")
    } else {
        print("\(i) is not a prime numbe")
    }
}