素数检查器每次返回相同的结果

时间:2015-01-19 03:03:32

标签: ios xcode swift

我是一名初学程序员,学习Swift并制作了一个基本的素数检查器。无论它只给出一个结果,而不是根据是否改变,数字是素数。任何帮助将不胜感激。

@IBAction func primeCheck(sender: AnyObject) {

var numberInt  = number.text.toInt()
var isPrime = true

    if number != nil {        
        if numberInt == 1 {      
            isPrime = false
        }

        if numberInt != 1 {         
            for var i = 2; i < numberInt; i++ {        
                if numberInt! % i == 0 {
                    isPrime = false
                } else {
                    isPrime = true
                }
            }
        }

    }

    if isPrime == true {
        result.text = "\(numberInt!) is a prime number!"
    } else {
        result.text = "\(numberInt!) is not a prime number!"
    }

}

5 个答案:

答案 0 :(得分:1)

我有另一种可能的解决方案。起初我除以2,因为它不能是素数。然后循环直到数字为素数或数字除以2小于分频器。

@IBAction func primeCheck(sender: AnyObject) {

    var numberInt  = number.text.toInt()
    var isPrime = true
    var divider = 3

    if number < 2 || (number != 2 && number % 2 == 0) {
        isPrime = false
    }

    // you only have to check to half of the number
    while(isPrime == true && divider < number / 2){
        isPrime = number % divider != 0
        divider += 2
    }

    if isPrime == true {
        result.text = "\(numberInt!) is a prime number!"
    } else {
        result.text = "\(numberInt!) is not a prime number!"
    }
}

答案 1 :(得分:0)

逻辑中的错误出现在本节中:

if numberInt! % i == 0 {
    isPrime = false
} else {
    isPrime = true
}

在函数的顶部,您将isPrime初始化为true,因此在循环中,您只需要查找证明数字 prime的情况。您不需要再次设置isPrime = true,所以只需删除其他条件:

if numberInt! % i == 0 {
    isPrime = false
}

答案 2 :(得分:0)

你实际上有两个功能。一个用于检查数字是否为素数,另一个用于显示结果。分离这些使得一切都更容易管理。

// function to check primality and return a bool
// note that this can only accept a non optional Int so there is
// no need to check whether it is valid etc...
func checkNumberIsPrime(number: Int) -> Bool {
    // get rid of trivial examples to improve the speed later
    if number == 2 || number == 3 {
        return true
    }

    if number <= 1 || number%2 == 0 {
        return false
    }

    // square root and round up to the nearest int
    let squareRoot: Int = Int(ceil(sqrtf(Float(number))))

    // no need to check anything above sqrt of number
    // any factor above the square root will have a cofactor
    // below the square root.
    // don't need to check even numbers because we already checked for 2
    // half the numbers checked = twice as fast :-D
    for i in stride(from: 3, to: squareRoot, by: 2) {
        if number % i == 0 {
            return false
        }
    }

    return true
}

// function on the button. Run the check and display results.
@IBAction func primeCheck(sender: AnyObject) {
    let numberInt? = numberTextField.text.toInt() // don't call a text field "number", it's just confusing.

    if let actualNumber = numberInt {
        if checkNumberIsPrime(actualNumber) {
            resultLabel.text = "\(actualNumber) is a prime number!" // don't call a label "result" call it "resultLabel". Don't confuse things.
        } else {
            resultLabel.text = "\(actualNumber) is not a prime number!"
        }
    } else {
        resultLabel.text = "'\(numberTextField.text)' is not a number!"
    }
}

这使得阅读和维护变得非常容易。

答案 3 :(得分:-1)

我不知道swift,但也许这会破坏你的代码:

如果是号码! &LT;&LT;

要做更快的算法,你可以只搜索从2到sqrt(numberInt)的除数。 (定理)

答案 4 :(得分:-1)

在您发现该号码可以被另一个号码分割后,您必须退出循环。同样对于黄金检查,您只需要检查可分性,直到数字的平方根。

您还可以使用可选绑定来提取numberInt并检查是否为nil。这是快速的方式。

@IBAction func primeCheck(sender: AnyObject) {

    var isPrime = true
    if let numberInt  = number.text.toInt() {

        if numberInt == 1 {
            isPrime = false /
        }
        else // Add else because you dont have to execute code below if number is 1
        {
            if numberInt != 1 {
                for var i = 2; i * i <= numberInt; i++ { // Only check till squareroot
                    if numberInt % i == 0 {
                        isPrime = false
                        break // Break out of loop if number is divisible.

                    } // Don't need else condition because isPrime is initialised as true.
                }
            }
        }

       if isPrime {
          result.text = "\(numberInt) is a prime number!"
       } else {
          result.text = "\(numberInt) is not a prime number!"
       }
    }

}

平方根检查的原因:Why do we check up to the square root of a prime number to determine if it is prime?

您可以通过将质数检查重构为单独的函数来进一步优化代码。

func isPrime(number:Int) -> Bool
{
    if number == 1 {
        return false
    }
    else
    {
        if number != 1 {
            for var i = 2; i * i <= numberInt; i++ {
                if numberInt % i == 0 {
                    return false
                }
            }
        }
    }
    return true
}

@IBAction func primeCheck(sender: AnyObject) {

    if let numberInt  = number.text.toInt() {

        if isPrime(numberInt) {
            result.text = "\(numberInt) is a prime number!"
        } else {
            result.text = "\(numberInt) is not a prime number!"
        }
    }

}