【问题标题】:Check if a number is prime?检查一个数字是否是素数?
【发布时间】:2015-09-15 07:48:14
【问题描述】:

我正在尝试制作一个检查数字是否为质数的应用程序。

有人可以帮我查一下号码吗?

我需要一个简单的答案,而不是非常先进的算法。我是编程新手。

【问题讨论】:

标签: swift


【解决方案1】:

这是 Swift 3 中的功能解决方案:

func isPrime(_ number: Int) -> Bool {
    return number > 1 && !(2..<number).contains { number % $0 == 0 }
}

它首先确保数字大于一,然后创建一个从 2 到数字(不包括数字)的范围,并检查数字不能被范围内的每个数字整除

【讨论】:

  • 功能性口红超过最慢算法
  • 这对于大量数据来说非常慢。假设 N 可被 i 整除需要 1 ms。因此假设,N = 1500450271 (Prime) 所用时间 = 1 毫秒 * 分割数 -> 1 毫秒 * 1500450271 -> 11.5 天。!!或者,1 毫秒 * 分割数 = 1 毫秒 * 1500450271 的平方根 = 大约 40000 毫秒 = 40 秒。
【解决方案2】:

最快的 Prime 检查器

Swift 4.2,Xcode 10.1

这个素数检查函数和扩展是最有效的,因为它只检查 整数的可分性。

复杂性:


解决办法:

func isPrime(_ n: Int) -> Bool {
    guard n >= 2     else { return false }
    guard n != 2     else { return true  }
    guard n % 2 != 0 else { return false }
    return !stride(from: 3, through: Int(sqrt(Double(n))), by: 2).contains { n % $0 == 0 }
}

扩展:

extension Int {
    var isPrime: Bool {
        guard self >= 2     else { return false }
        guard self != 2     else { return true  }
        guard self % 2 != 0 else { return false }
        return !stride(from: 3, through: Int(sqrt(Double(self))), by: 2).contains { self % $0 == 0 }
    }
}

工作原理

与其他答案相比,此代码的优势在于它不检查冗余数字。这段代码只检查一半的数字,直到所需数字的平方根。


【讨论】:

  • 是的,@MartinR 完全不同,它不会检查 2 的倍数,而 @shokuroff's answer 会检查。我对两者进行了基准测试,发现我的答案比另一个答案快 5-6 倍。
  • 那是指你四月份的版本。我已删除我的评论,因为您的代码已更改。
【解决方案3】:

由于我的声誉,我无法回复,但我发现 Wayne Ellery 的 方法非常棒。但是,如果可能的话,请稍作修复..

// that's Swift 3.1
import Foundation

func isPrime(_ number: Int) -> Bool {
    // right below
    if number == 2 || number == 3 { return true }
    let maxDivider = Int(sqrt(Double(number)))
    return number > 1 && !(2...maxDivider).contains { number % $0 == 0 }
}

值大于sqrt(number) 的整数number 的所有除数都不是必需的。

【讨论】:

  • 在number == 2的情况下这是错误的,因为在这种情况下maxDivider是2的平方根,小于2,不能形成上键。
【解决方案4】:

一个简单的方法是检查所有因子直到数字的平方根。这不是最有效的方法,但对于您可能在 iPhone 应用程序中输入的大多数数字来说已经足够了。 (更复杂的算法见https://en.wikipedia.org/wiki/Primality_test)。

function is_prime(n: int)
    if n <= 1
        return false

    if n <= 3
        return true

    i = 2
    while i*i <= n
        if n % i == 0
           return false
        i = i + 1
    return true

【讨论】:

  • 我已经从 @Steven Kryskalla 的更新中回滚,该更新建议增加 2——这完全是错误的:i 不是被检查的数字,而是除数。除数可以是偶数或奇数,因此必须加一。例如,如果您尝试更新的算法,它会告诉您 45 是素数。
  • 好收获。我认为原始编辑器试图做的只是测试一次 2 的可除性,这样你可以从 3 开始 i 并每次增加 2,但代码不正确。
【解决方案5】:

单班轮:

  1. 更快地丢弃非素数(感谢惰性评估)。
  2. 缩小搜索除数的范围。
func isPrime(_ n: Int) -> Bool {
  return (2...Int(Double(n).squareRoot())).lazy.filter({ n % $0 == 0 }).first == nil
}

【讨论】:

  • 令人惊讶的是,这个问题已经超过 4 年了,相对简单,我仍然得到很好的答案。
  • 快速而优雅。用 1_000_000_000 范围内的数字进行测试
【解决方案6】:

Swift 2 示例:

func is_prime(n: Int) -> Bool {
    if n <= 1 {
        return false
    }
    if n <= 3 {
        return true
    }
    var i = 2
    while i*i <= n {
        if n % i == 0 {
            return false
        }
        i = i + 1
    }
    return true
}

【讨论】:

    【解决方案7】:
    func divides(a: Int, b: Int) -> Bool {
        return a % b == 0
    }
    
    func countDivisors(number: Int) -> Int {
        var cnt = 0
        for i in 1...number {
            if divides(a: number, b: i) {
                cnt+=1
            }
        }
        return cnt
    }
    
    
    
    func isPrime(number: Int) -> Bool {
        return countDivisors(number: number) == 2
    }
    
    isPrime(number: 7)
    

    【讨论】:

    • 有趣的方法,使用直观的素数思维方式。
    • 非常直观的方法。真的很喜欢蒂娜
    【解决方案8】:
    func checkPrimeOrNot(numberToCheck:Int)-> Bool{
        var isPrime : Bool = false
        if numberToCheck > 2  {
            for  n in 2...(numberToCheck - 1) {
                isPrime = (numberToCheck % n ) == 0  ? false : true
                if !isPrime{
                    break
                }
            }
        } else {
            isPrime = numberToCheck == 1 ? true : false
            isPrime = numberToCheck == 0 ? false : true
        }
        return isPrime
    }
    

    你可以这样调用这个函数

    让 primeNumber = checkPrimeOrNot(numberToCheck: 23)

    【讨论】:

    • 您好,感谢您的贡献。您能否编辑您的答案并提供一些解释?
    • 适合初学者的简单方法。投票以激励
    【解决方案9】:
    func FindPrime(number: Int) -> Bool {
        guard number >= 2 else { return false }
    
        for i in 2 ..< number {
            if number % i == 0 {
                return false
            }
        }
    
        return true
    }
    
    1. 这个函数的问题是它在计算上 昂贵:16,777,259 是一个素数,所以这个解决方案将 从 2 划分到 16,777,258 并发现它们都不起作用 在确定这个数是素数之前。

    2. 考虑一下:如果数 n 不是素数,则意味着它可以通过 x 和 y 两个因数相乘得到。如果这两个 数字大于 n 的平方根,则 x * y 将是 大于n,这是不可能的。所以,我们可以确定在 x 或 y 中至少有一个小于或等于 n 的平方根。

    func FindPrime(number: Int) -> Bool {
        guard number >= 2 else { return false }
        guard number != 2 else { return true }
        let max = Int(ceil(sqrt(Double(number))))
    
        for i in 2 ... max {
            if number % i == 0 {
                return false
            }
        }
    
        return true
    }
    

    【讨论】:

      【解决方案10】:

      Swift 3 中:

      func prime(_ number: Int) -> Bool {
          return (1...number).filter({number % $0 == 0}).count <= 2
      }
      

      【讨论】:

      • +1 表示单行优雅。请注意,正如在其他地方所说,只有直到目标数字的 平方根 的数字才需要检查因子。想一想:如果 16 或 17 不是素数,那么当您检查它是否被 5 整除时,您就会知道。对于任何合数,因子在 sqrt 周围“翻转”。取 16:(1, 16), (2, 8), (4, 4), (8, 2), (16, 1)。检查 8 是多余的,因为您必须在到达那里的路上还检查了 2。用“m”和“n”替换所有数字,你就有了证明! (呃,我把它留作练习:D)
      【解决方案11】:

      我刚刚完成了这个程序来学习语法 Swift4。这是我的结尾:

      import Foundation
      import Darwin
      
      var Timestamp: Double {
          return (NSDate().timeIntervalSince1970)
      }
      
      func checkPrime(number: Int) -> String {
          let num: Double = Double(number)
          let squareRoot: Double = Double(sqrt(num))
          let sqr: Int = Int(floor(squareRoot))
          var i: Int = 3
          while i <= sqr {
              if number % i == 0 {
      
                  return "Too bad... \(number) is not a prime number, you can divide it by \(i) :/"
              }
              i += 2
          }
      
          return "You chose \(number) wisely. Definitely a prime number"
      }
      
      func isPrime(check: Int) -> String {
          switch check {
              case check where check <= 1 :
                  return "Neither 1 nor numbers below are prime numbers."
              case 2 :
                  return "Congratulations ! \(check) is the only even prime number !"
              case let check where check % 2 == 0 :
                  return "There is only one even prime number, and it's definitely not \(check)..."
              default :
                  return checkPrime(number: check)
          }
      }
      
      print("Please write Int to check if it's prime")
      if let typed: String = readLine() {
          if let num: Int = Int(typed) {
              let start = Timestamp
              print(isPrime(check: num))
              print("calculated in \((Timestamp - start)*1000) milliseconds")
          } else {
              print("Please choose an integer between 0 and \(Int.max)")
          }
      }
      

      这里发生的事情很简单,但它帮助我理解了一些我想与像我这样的新手分享的东西!

      首先我找到了一个时间戳函数here 来计算我的程序需要多少时间来检查一个数字是否为素数。这与素数无关,所以我们不要谈论它。

      我的第一个大问题是获取用户的输入。在 Swift 中寻找等效的提示后,我意识到我总是得到一个字符串作为答案。
      我发现 this convenient way 对我理解 Swift 中的类型以及如何从 String 到 Int 有很大帮助。

      这就是寻找质数的核心:

      首先,函数 isPrime 评估显而易见的。
      我知道如果它低于或等于 1,它就不是质数。我学到了非常奇怪的语法,我真的需要记录下来

      switch check {
          case check where check <= 1
      }
      

      我知道 2 是唯一的偶素数
      我知道所有其他偶数都是不是素数(语法很奇怪)

      如果我通过了这个测试,那么我真的可以检查这个数字是否是素数:

      我了解到,您不必评估从 3(请记住,我们排除了 2 和下面的)到潜在质数的所有数字,原因有两个:

      • 如果是2的任意倍数的倍数,则已经排除了
      • 如果不能将它与从 3 到其平方根的任何整数相乘,则它是素数。 (more infos here)

      所以从这里我必须得到我的号码的平方根,为此我需要将我的号码从 Int 切换到 Double。我需要将结果存储到 Int var 中,以便将其与递增的数字 i(从 3 到 sqrt)进行比较。

      之后我只需要检查我的数字 % i 是否不等于 0,在这种情况下它不是质数。由于我已经消除了偶数,我可以在每个循环中将 i 增加 2,因此我只检查奇数。

      这是我在这里的第一个贡献,所以我真的希望它会有所帮助。我很确定我的代码远非完美,所以请毫不犹豫地纠正/改进它!

      【讨论】:

        【解决方案12】:
        func primeOrNot(input : Int){
            
            var flag : Bool = false;
            if (input > 2){
                for i in 2...input/2{
                    if(input % i == 0){
                        flag = true
                        break;
                    }
                }
            }else{
                flag = true
            }
            let result = (flag == false) ? "\(input) is prime!" : "\(input) is not prime!"
            debugPrint(result)
        }
        

        【讨论】:

          【解决方案13】:
          //not the best, but it works
          let checkPrimeNumber = { (number: Int)-> [Int] in
          var arr = Array<Int>()
          for i in 2...number {
              if i==2 || i==3 || i==5 || i==7 {
                  arr.append(i)
              }
              if (i%2 != 0) && (i%3 != 0) && (i%5 != 0) && (i%7 != 0) {
                  arr.append(i)
              }
          }
          return arr
          

          }

          打印(checkPrimeNumber(10))

          【讨论】:

            【解决方案14】:

            以下是一个简单的蛮力函数,用于确定一个数是否为素数。它将目标数除以小于自身的所有正整数(1 除外)。如果任何除法的余数为零,那么显然目标数不是素数。如果没有找到这样的除数,则该数字是素数。

            func isNumberPrime(_ number : Int) -> Bool{
                for n in 2..<number {
                    if( number % n == 0){
                        return false
                    }
                }
                return true
            }
            

            【讨论】:

            • 虽然这篇纯代码帖子可能会回答这个问题,但请添加解释为什么会这样。
            【解决方案15】:
            func isPrime(n : Int) -> Bool{
                var t = true
                if n <= 1 {
                    print("Choose a number higher than one")
                } else {
                    for y in 2...n {
                        if y == n {
                            t = true
                            break
                        } else if n % y == 0 {
                            t = false
                            break
                        } else if n % y != 0 {
                        }
                    }
                }
                return t
            }
            
            print(isPrime(n: 51))
            // This only answers for the number inputted, in this case "51"
            

            【讨论】:

              【解决方案16】:

              质数的形式为 6f ± 1,不包括 2 和 3,其中 f 是任意整数

              func isPrime(_ number: Int) -> Bool 
              {
              
                   if (number <= 1)
                   {
                      return false;
                   }   
              
                   // The check for the number 2 and 3
                   if (number <= 3)
                   {
                      return true;
                   }
              
                   if (number%2 == 0 || number%3 == 0)
                   {
                      return false;
                   }
              
                   for var i in stride(from: 5, to: number/2, by: 6)
                   {
              
                      if (number%i == 0 || number%(i+2) == 0)
                      {
                         return false;
                      }   
                   }
              
                   return true;
              }
              

              解的时间复杂度:O(sqrt(n))

              【讨论】:

                【解决方案17】:

                只添加这 2-3 行代码:

                for i in 2..<number {
                    if (number % i == 0) {
                        print("\(number) is not prime.")
                    }
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-01-17
                  • 2016-08-21
                  • 1970-01-01
                  • 2018-01-13
                  • 1970-01-01
                  • 2011-05-06
                  相关资源
                  最近更新 更多