【问题标题】:Identify prime number识别素数
【发布时间】:2017-08-20 17:20:36
【问题描述】:

由于某种原因,它总是给我错误的结果。无论将什么数字分配给“数字”变量,它始终是 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 是可选的?没有可能是素数 ;-)

标签: swift if-statement primes


【解决方案1】:

问题 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 % $0 == 0 }

【讨论】:

  • 我真的很怀念 Swift 中 every 对应的 contains(2..&lt;number).every { number % $0 != 0 }
  • @Sulthan 那太好了
  • 我有它作为扩展,但它不一样:)
  • sqrt(number)为上限就足够了。
  • 最后一行应该是 let isPrime = !(2...upperLimit).contains { n % $0 == 0 } 否则 number = 4,9,25... 算作素数
【解决方案2】:

因为 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)

【讨论】:

  • i 应该从 2 开始,而不是 1。任何数字模 1 都将返回 0。
  • 正确。修好了。
  • 检查到sort(number)也足够了。
  • @DávidPásztor 我相信你的意思是sqrt
【解决方案3】:

在处理此类问题时,不要害怕拿出一张纸,手动查看循环中发生了什么。

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

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

对于i = 1number = 6

6 mod 1 = 0, isItPrime = false


对于i = 2number = 6

6 mod 2 = 0isItPrime = false


对于i = 3number = 6

6 mod 3 = 0, isItPrime = false


对于i = 4number = 6

6 mod 4 = 2, isItPrime = true


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

6 mod 5 = 1, isItPrime = true


我们可以看到问题在于最后一次迭代的模块总是 1,因此导致您的 else 子句被执行。

【讨论】:

    【解决方案4】:

    它总是返回 true,因为你的 while 循环没有按照你想要的方式工作。目前,它循环直到inumber 小1。在循环的最后一次运行中,number % i == 0 为 false,因此您的代码将 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 部分

    希望这会有所帮助!

    【讨论】:

      【解决方案5】:
      // 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-20
        • 1970-01-01
        • 2017-09-13
        • 2018-03-18
        • 2021-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多