Quel est le problème avec ma logique? Comment 9 peut-il sortir de cette boucle à la fois comme un nombre premier et non comme un nombre premier?

Cela fonctionne comme prévu pour 0, 1, 2, 3, 4, 5, 6, 7, 8 mais se bloque sur 9 ...


var userInput = 9

if userInput == 0 {
    print("0 is not a prime number")
} else if userInput == 1 {
    print("1 is not a prime number")
} else if userInput == 2 {
    print("2 is a prime number")
} else {
    for var i = 2; i < userInput; i = i + 1 {
        if userInput % i == 0 {
            print("\(userInput) is not a prime number")
            break
        } else {
            print("\(userInput) is a prime number")
            break
        }
    }
}
0
MartyJ 5 janv. 2016 à 20:45

3 réponses

Meilleure réponse

Cette logique est imparfaite:

for var i = 2; i < userInput; i = i + 1 {
    if userInput % i == 0 {
        print("\(userInput) is not a prime number")
        break
    } else {
        print("\(userInput) is a prime number")
        break
    }
}

Le if-else est faux. Vous devez plutôt parcourir la partie entière if de la boucle for d'abord , en vérifiant si chaque nombre est un facteur (if userInput % i == 0) , encore et encore; alors et alors seulement , si vous avez terminé la boucle et toujours n’a pas découvert de facteur, pouvez-vous déclarer que ce doit être un premier.

Cependant, vous aurez du mal à réussir à écrire cette logique si vous configurez tout à un niveau supérieur plat comme vous l'avez fait. Le problème est que vous n'avez aucun moyen de faire une vraie sortie lorsque vous êtes au plus haut niveau. Votre logique nécessite donc que vous mettiez tout dans une fonction, à partir de laquelle vous pouvez faire une sortie anticipée forcée en disant return.

Dans cette réécriture, je l'ai fait, en plus j'ai utilisé un switch qui est plus clair (et plus rapide) que votre if...else if:

func testForPrime(userInput:Int) {
    switch userInput {
    case 0: print("0 is not a prime number")
    case 1: print("1 is not a prime number")
    case 2: print("2 is a prime number")
    default:
        for i in 2..<userInput {
            if userInput % i == 0 {
                print("\(userInput) is not a prime number")
                return
            }
        }
        print("\(userInput) is a prime number")
    }
}

Et voici comment le tester:

for i in 0...20 {testForPrime(i)}

Production:

0 is not a prime number
1 is not a prime number
2 is a prime number
3 is a prime number
4 is not a prime number
5 is a prime number
6 is not a prime number
7 is a prime number
8 is not a prime number
9 is not a prime number
10 is not a prime number
11 is a prime number
12 is not a prime number
13 is a prime number
14 is not a prime number
15 is not a prime number
16 is not a prime number
17 is a prime number
18 is not a prime number
19 is a prime number
20 is not a prime number

(Veuillez également noter que j'ai utilisé une boucle for de style Swift au lieu de votre boucle for de style C. Vous devriez vous habituer au style Swift, car la boucle for de style C sera bientôt supprimée du langage .)

4
matt 5 janv. 2016 à 18:12

Supprimez l'une des instructions break. La boucle doit s'exécuter complètement jusqu'à ce qu'elle trouve une condition où ce n'est pas un nombre premier. S'il ne trouve pas ladite condition, c'est un nombre premier.

var userInput = 9

if userInput == 0 {

    print("0 is not a prime number")

} else if userInput == 1 {

    print("1 is not a prime number")

} else if userInput == 2 {

    print("2 is a prime number")

} else {

    for var i = 2; i < userInput; i = i + 1 {

        if userInput % i == 0 {

            print("\(userInput) is not a prime number")
            break

        } else {

            print("\(userInput) is a prime number")
            // no break here

        }
    }
}

Ou un peu plus utile:

La logique est intégrée dans une fonction, vous pouvez donc utiliser return pour le flux de contrôle au lieu de break. Puisqu'il y a un return true à la fin, vous n'avez qu'à rechercher les conditions false. Si ce n'est pas un premier, vous utilisez return false pour échapper à la fonction et le return true à la fin ne sera jamais appelé.

extension Int {

    func isPrimeNumber() -> Bool {

        switch self {
        case 0 : return false
        case 1 : return false
        default :
            for i in 2..<self {
                if (self % i) == 0 {
                    return false
                }
            }
        }
        return true
    }
}

userInput.isPrimeNumber()

La fonction est placée dans une extension vers Int afin que vous puissiez simplement appeler la fonction depuis userInput.

5
R Menke 5 janv. 2016 à 18:12

Mes solutions semblent terribles dans la zone de commentaire. Je les ai recollés ici. Merci encore pour toute votre aide!


var uI = 9

var isPrime = true

if uI == 0 || uI == 1 {

    isPrime = false

}

for var i = 2; i < uI; i++ {

    if uI % i == 0 {

        isPrime = false  
    }
}

if isPrime {

    print("\(uI) is prime!")

} else {

    print("\(uI) is not prime”)

}

var uI = 11

var isPrime = true

if uI == 0 || uI == 1 {

    isPrime = false

}

var i = 2

while i < uI {

    if uI % i == 0 {

        isPrime = false

    }
    i++

}

if isPrime {

    print("\(uI) is prime!”)

} else {

    print("\(uI) is not prime”)

}

1
R Menke 6 janv. 2016 à 15:58