UILabel не обновляется при каждом расчете - PullRequest
0 голосов
/ 27 октября 2018

Я пытаюсь сделать верификатор простого числа, который видит, является ли число простым или нет.Проблема в том, что когда я вставляю простое число, например, 13, в качестве первого числа, которое я вставляю, оно говорит, что это простое число.После того, как я вставляю не простое число, такое как 48, оно говорит, что это не простое число.Но теперь, если я вставлю простое число, он скажет, что это не простое число.

import UIKit

class ViewController: UIViewController
{
    var D = 1
    var C = 0
    @IBOutlet weak var labelOUT: UILabel!
    @IBOutlet weak var numberIN: UITextField!

    @IBAction func Clear(_ sender: Any)
    {
      labelOUT.text = ""
    }

    @IBAction func calculate(_ sender: Any)
    {
        let number = Int(numberIN.text!)

        repeat
        {
            if (number! % D == 0)
            {
                C = C + 1
            }
            else
            {
            }
            D = D + 1
        }while(D <= number!)

        if ( C <= 2 )
        {
            labelOUT.text = "prime"
        }
        else
        {
            labelOUT.text = "not prime"
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        labelOUT.text = ""
    }
}

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Если вы хотите быстро исправить, объявите C и D внутри функции calculate().

Вам не нужно находить все делители, чтобы проверить, является ли число простым или нет. Как только вы найдете a делитель, число не будет простым.

Вот более эффективный способ проверки, является ли текст в текстовом поле простым или нет:

@IBAction func calculate(_ sender: Any)
{
    guard let number = Int(numberIN.text!) else 
    {
        fatalError("Not a number")
    }

    let isPrime = checkIfPrime(number)
    labelOUT.text = isPrime ? "prime" : "not prime"
}

Вызывает эту функцию, чтобы проверить, простое ли number:

func checkIfPrime(_ n: Int) -> Bool 
{
    switch n 
    {
    case ...1:
        return false
    case 2...3:
        return true
    default:
        var isPrime = true
        let maximumPossibleDivisor = Int(sqrt(Double(n)))

        var divisor = 2
        repeat
        {
            if (n % divisor == 0)
            {
                isPrime = false
                break
            }
            divisor += 1
        } while (divisor <= maximumPossibleDivisor)

        return isPrime
    }
}

Используется тот факт, , что у составного числа есть делитель между 2 и его корневым квадратом.


Более эффективная версия checkPrime() использует тот факт, что простые числа, кроме 2 и 3, можно записать как 6X - 1 или 6X + 1

func checkIfPrime(_ n: Int) -> Bool {
    switch n {
    case ...1:
        return false
    default:
        if n % 2 == 0 || n % 3 == 0
        {
            return false
        }

        let maximumPossibleDivisor = Int(sqrt(Double(n)))
        var divisor = 5
        while (divisor <= maximumPossibleDivisor)
        {
            if n % divisor == 0 || n % (divisor + 2) == 0
            {
                return false
            }
            divisor += 6
        }

        return true
    }
}

Вот симпатичный способ проверки простоты числа с помощью регулярного выражения:

extension Int {
    func isPrime() -> Bool {
        guard self >= 0 else { fatalError("Primality is only checked for positive numbers") }
        let regex = try! NSRegularExpression(pattern: "^.?$|^(..+?)\\1+$")
        let str = Array(repeating: "1", count: self).joined()
        let range = NSMakeRange(0, self)
        return regex.matches(in: str, range: range).count == 0
    }
}

Принцип работы регулярного выражения подробно объясняется в здесь и там .


Подробнее о тестах на простоту смотрите здесь .

0 голосов
/ 27 октября 2018

Вам необходимо сбросить C и D. в верхней части вашего метода Calculate ().

@IBAction func calculate(_ sender: Any)
{ 
    D = 1
    C = 0

В противном случае ранее вычисленные результаты влияют на ваш недавно вычисленный результат.В следующий раз, когда вы застрянете, установите несколько контрольных точек, внимательно изучите алгоритм и изучите все вычисления.Затем вы либо узнаете, что сделали неправильно, либо, по крайней мере, узнаете, какая строка не рассчитана так, как вы ожидали, и сможете сфокусировать вопрос на этой строке.

...