nth prime number in swift

2020-02-16 02:01发布

问题:

I'm trying to find the nth prime number in xCode's Swift, but I can't seem to get this working, it just gives a list of prime numbers.

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
}

回答1:

Making minimal changes to your code, but, as commenter said, adding termination logic:

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
}


回答2:

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 { $0.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


回答3:

[Note: this code returns the nth prime, as required; not just 50 or 51, both non-primes.]

The n that you specified as an argument is totally ignored thus your computation terminated if and when prime became 51. All the primes under 50 were printed and a coincidental 51 is returned. If you want the nth prime, you need to a) count up the primes as you encounter them and b) stop when you've got the nth.

You also have the issue to deal with of 'I want the 20th prime but I'm only looking for primes under 50' - there might not be a prime.

And, you are performing prime % divisor with divisor < prime but that divisor never needs to be more than prime/2.

All this together, with improvement in style leads to:

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

and some results:

 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

I encourage you to try n of 1000!