【问题标题】:how to create a function that gives a prime number + bool value?如何创建一个给出素数 + bool 值的函数?
【发布时间】:2019-05-31 14:24:45
【问题描述】:

从昨天开始我一直在为此苦苦挣扎,如何创建一个包含素数列表并返回“素数 + 真/假”的函数 例如:

2 真 3 对 4 假 5 对

它在 Swift 5 中,第一个函数 primecheck 运行良好,问题出在第二个函数 PrimeList

func primecheck (numbers:Int) -> Bool{ 

    var prime = true

    if numbers == 1 || numbers == 0 || numbers == 2{
        prime = true

    }
    if numbers > 2{
        for i in 2...numbers - 1{
            if numbers % i == 0 {
                prime = false

            }

        }
    }
    if numbers == 1 || numbers == 0 || numbers == 2{
        prime = true

    }

    if numbers < 0{
        prime = false
    }
    return prime
}


func PrimeList(maxP:Int) -> [(num1:Int, num2:Bool)] {


    var primes: [(num1:Int, num2:Bool)] = []

    for i in 1...maxP {

        if primecheck(numbers:i){
            print(i)
            primes[i - 1] = (i, true)

        } else {
            primes[i - 1] = (i, false)
        }
    }
  //  isPrime[0] = true
  //  isPrime[1] = true

    return primes
}

print(PrimeList(maxP:20))

预期输出:

print(primeList(maxP:20))
// 2 true
// 3 true

// 4 false
...
// 20 false

但总是出现这个错误:

执行被中断,原因:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)。

【问题讨论】:

  • 改用primes.append((i, true))primes.append((i, false)),或直接使用primes.append((i, primecheck(numbers: i)))
  • 0 和 1 根据定义不是素数
  • 让我们简化您的情况:var array: [Int] = []; array[0] = 3 这是同样的错误,在控制台中,还有一个有趣的消息:“致命错误:索引超出范围”。阅读array[0] = 3,如:给我索引 0 处的项目,并将其替换为值 3。好吧,“给我索引 0 处的项目”会导致崩溃(并且该日志是有道理的)。
  • 这里的简单解决方案当然是在结果数组中只包含素数的数字而忘记这个布尔值

标签: arrays swift tuples


【解决方案1】:

如果对您有意义,请参阅下面的答案:

func isPrime(_ number: Int) -> String {

    return "\(number) \(number > 1 && !(2..<number).contains { number % $0 == 0 })"
}

func PrimeList(maxP:Int) {
    var array = [String]()
    for number in 0...maxP {
        array.append(isPrime(number))
    }
    print(array)
}

调用方法:

PrimeList(maxP: 20)

回答:

[“0 假”、“1 假”、“2 真”、“3 真”、“4 假”、“5 真”、“6 假”、“7 真”、“8 假”、“9 假”、“10 假”、“11 真”、“12 假”、“13 真”、“14 假”、“15 假”、“16 假”、“17 真”、“18 假”、“19 真”、“20 假”]

【讨论】:

  • 0 和 1 不是 素数
  • @mansonflirr 如果您找到了帮助您解决此问题的答案,请将其标记为已接受,而不是发布这样的评论。这将帮助那些面临与您类似问题的未来读者,当然会受到撰写答案的人的赞赏
【解决方案2】:

您可以使用mapreduce(into:_:) 方法生成元组的primeList 数组。

使用reduce(into:_:)

func primeList(maxP:Int) -> [(num1:Int, num2:Bool)] {
    return (1...maxP).reduce(into: [(num1:Int, num2:Bool)](), { $0.append((num1:$1, num2:primecheck(number:$1))) })
}

而且你不需要检查直到n-1 来查找一个数字是否是素数。您可以检查直到nsquare root

func primecheck(number: Int) -> Bool {
    if number < 2 { return false }
    if 2...3 ~= number { return true }
    return !(2...Int(sqrt(Double(number)))).contains { number % $0 == 0 }
}

【讨论】:

    【解决方案3】:

    您的程序正在崩溃,因为您无法在 Swift 中对空数组进行索引。您应该使用 append 将项目添加到您的数组中。

    虽然不是通过附加项目来创建数组,但这是使用map 的理想场所:

    func primeList(maxP: Int) -> [(num1: Int, num2: Bool)] {
        return (1...maxP).map { ($0, primecheck(numbers: $0)) }
    }
    

    说明:

    map 创建一个数组。在这种情况下,它从(1...maxP) 范围内获取每个项目,并使用提供的闭包将其转换为原始值的 tuple 以及使用该值调用primecheck 的结果。结果是所需的数组,其中的值与布尔值配对,指示它们是否为素数。


    您的primecheck 函数可以通过使用guard 立即清理return false 用于不大于1 的数字。如果您找到一个能将输入均分的数字,您可以立即return false,否则,如果没有找到,您可以立即return true

    func primecheck (numbers:Int) -> Bool {
        guard numbers > 1 else { return false }
    
        for i in 2..<numbers {
            if numbers % i == 0 {
                return false
            }
        }
    
        return true
    }
    

    注意事项:

    1. 您可以通过在i * i &gt; numbers 时放弃检查除数来进一步优化primecheck。在for 循环的顶部添加guard i * i &lt;= numbers else { return true }。或者,将除数范围的上限设为Int(sqrt(Double(numbers)))
    2. 2...numbers - 1 已改写为 2..&lt;numbers
    3. 函数名称应以小写字母开头。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-31
      • 2022-07-06
      • 1970-01-01
      • 2017-05-25
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多