识别质数

Identify prime number

出于某种原因,它总是给我错误的结果。无论分配给 "number" 变量的数字是什么,它总是 isItPrime = true

这是我的代码:

let number = 6
var i = 1
var isItPrime: Bool?
while i < number {
    if number % i == 0 {
        isItPrime = false
    } else {
        isItPrime = true
    }
    i += 1
}
print(isItPrime)

有人可以向我解释我的代码有什么问题以及为什么 isItPrime bool 输出总是 true 吗?

因为 isItPrime 在后续迭代中被覆盖,最后检查的数字 number - 1 将始终将 isItPrime 设置为 true,因为 numbernumber - 1是互质的。

不是将值保存为布尔值,而是在发现数字不是质数时结束循环:

let number = 6
var isItPrime: Bool = true
for i in 2 ..< number {
    if number % i == 0 {
        isItPrime = false
        break // end the loop, as we know that the number is not a prime.
    }
}
print(isItPrime)

问题 1

while 循环的最后一次迭代

while i < number {
    if number % i == 0 {
        isItPrime = false
    } else {
        isItPrime = true
    }
    i += 1
}

覆盖结果。

所以你总是得到以下结果

if number % (number-1) == 0 {
    isItPrime = false
} else {
    isItPrime = true
}

问题 2

终于每个数都可以除以1了,所以你应该从2开始i。 所以

let number = 6
var i = 2
var isItPrime = true
while i < number {
    if number % i == 0 {
        isItPrime = false
        break
    }
}
print(isItPrime)

重构

您可以使用函数式编程编写类似的逻辑

let number = 5
let upperLimit = Int(Double(number).squareRoot())
let isPrime = !(2...upperLimit).contains { number % [=13=] == 0 }

处理此类问题时,不要害怕拿出一张纸,手动查看循环中发生的情况。

您的循环将从 i = 1 转到 number = 5(因为 < 运算符。

考虑到这一点,我们手动执行每次迭代。

对于 i = 1number = 6

6 mod 1 = 0isItPrime = false


对于 i = 2number = 6

6 mod 2 = 0isItPrime = false


对于 i = 3number = 6

6 mod 3 = 0isItPrime = false


对于 i = 4number = 6

6 mod 4 = 2, isItPrime = true


循环的最后一次迭代,对于 i = 5number = 6

6 mod 5 = 1, isItPrime = true


我们可以看到问题在于最后一次迭代的模数始终为 1,因此导致执行 else 子句。

它总是返回真,因为你的 while 循环没有按你想要的方式工作。目前,它循环直到 inumber 小 1。在循环的最后 运行 期间,number % i == 0 为假,因此您的代码将 isItPrime 设置为 true

要解决此问题,请尝试以下代码:

let number = 6
var i = 2
var isItPrime: Bool?
while (i < number || isItPrime == false) {
    if number % i == 0 {
        isItPrime = false
    } else {
        isItPrime = true
    }
    i += 1
}
print(isItPrime)

你可能已经注意到我将 i 设置为 2,因为任何数字对 (%) 1 取模 (%) 都是 0

不过,我认为值得指出的是:

  1. 你应该把它变成一个方法

  2. 如果您最初将 isItPrime 设置为 true,则可以省略 if-else 语句的 else 部分

希望对您有所帮助!

// MARK: - Function

      func primeNo(_ num:Int,_ divisor :Int = 2){
            if divisor == num{
                print("Num is prime")
            }else{
                if num%divisor != 0{
                    primeNo(num, divisor + 1)
                }else{
                    print("num is not prime")
                }
            }
        }


// MARK: - Use
 primeNo(6)    

 out Put
 num is not prime