Java Primzahlen bis 8 testen?
In Java. Ich möchte alle Zahlen bis 8 testen lassen ob Sie Primzahlen sind oder nicht
Per Scanner wird die 8 eingelesen:
Am Ende soll ausgegeben werden:
Zahl 1 ist keine Primzahl
Zahl 2 ist Primzahl
Zahl 3 ist keine Primzahl
...
Zahl 8 ist keine Primzahl
Wie kriegt man dies hin: Doppelte for-Schleife?
2 Antworten
for (int i = 1; i <= 8; i++) { // Schleife über alle Zahlen von 1 bis 8
boolean isPrime = true; // isPrime erstmal auf true setzen. Später auf false setzen, wenn feststeht, dass es keine Primzahl ist
if (i == 1) {
isPrime = false; // 1 ist keine Primzahl. Müssen wir extra handeln, damit kommt die folgende Schleife nämlich nicht zurecht
}
for (int j = 2; j < i; j++) { // Schleife über alle Zahlen von 2 bis (ausgeschlossen) i
if (i % j == 0) {
isPrime = false; // Wenn teilbar, dann ist i keine Primzahl
}
}
System.out.println("Zahl " + i + "ist " + (isPrime ? "eine" : "keine") + " Primzahl");
}
Effizienter geht's natürlich immer, jo. Hatte zuerst auch ein break; innen stehen, aber dann dachte ich mir "Scheiß auf Performance, hauptsache er checkt wie's geht" und hab die simpelste/kürzeste Version geschrieben :D
Mit folgendem Code lässt sich überprüfen, ob ein Integer eine Primzahl ist:
public static boolean isPrime(int num) {
if(num > 2 && num % 2 == 0) {
System.out.println(num + " ist keine Primzahl.");
return false;
}
int top = (int) Math.sqrt(num) + 1;
for(int i = 3; i < top; i += 2) {
if(num % i == 0){
System.out.println(num + " ist keine Primzahl.");
return false;
}
}
System.out.println(num + " ist eine Primzahl.");
return true;
}
Quelle: https://codereview.stackexchange.com/questions/24704/efficiently-determining-if-a-number-is-prime
Für die Aufgabe des Fragestellers wird dies keinesfalls notwendig sein. Bei der offiziellen Software-Produktion dagegen grundsätzlich schon.
Danke: Allerdings müssen die Sache ohne eine Methode schreiben
In dem Falle würde man statt:
public static boolean isPrime(int num) { … }
eine for-Schleife benutzen:
for(int num = 1; num <= 8; num++) { … }
Die return-Statements können dann logischerweise ausgelassen werden.
Die return-Statements können dann logischerweise ausgelassen werden.
Dann würde beides geprintet werden...
Statt return würde man continue verwenden, ansonsten wird die Schleife vollständig abgebrochen.
Wollt ich zuerst auch sagen, dann ist mir aber aufgefallen:
continue würde sich dann aber nur auf die innere Schleife beziehen, geht also auch nicht.
Natürlich soll sich continue nur auf die innere Schleife beziehen, ansonsten werden die anderen Zahlen nicht überprüft. Den Code mit continue habe ich soeben überprüft und er funktioniert so wie gedacht.
ansonsten werden die anderen Zahlen nicht überprüft
Continue bricht die Schleife nicht ab, sondern fährt mit der nächsten Zahl fort. Warum sollten also die anderen Zahlen nicht überprüft werden, wenn es sich auf die äußere Schleife beziehen würde?
Oder meinst du bezogen auf das hier?
for(int i = 3; i < top; i += 2) {
if(num % i == 0){
System.out.println(num + " ist keine Primzahl.");
return false;
}
}
Da sollen die anderen Zahlen (die späteren i`s) ja auch nicht mehr überprüft werden, wenn es die Zahl keine Primzahl ist. Du willst doch schließlich nicht das "ist keine Primzahl" mehrfach ausgeben ....
und er funktioniert so wie gedacht.
Auch nur wegen dem ersten continue in der if-Abfrage vor der Schleife, das sich zu deinem Glück auf die äußere Schleife bezieht... Ansonsten bekäme man
1 ist eine Primzahl.
2 ist eine Primzahl.
3 ist eine Primzahl.
4 ist keine Primzahl.
4 ist eine Primzahl.
5 ist eine Primzahl.
6 ist keine Primzahl.
6 ist eine Primzahl.
7 ist eine Primzahl.
8 ist keine Primzahl.
8 ist eine Primzahl.
Und auch das war nur reines Glück.
Lass die Schleife mal bis 20 hoch zählen und schau, wie gut dein Code dann noch funkioniert....
1 ist eine Primzahl.
2 ist eine Primzahl.
3 ist eine Primzahl.
4 ist keine Primzahl.
5 ist eine Primzahl.
6 ist keine Primzahl.
7 ist eine Primzahl.
8 ist keine Primzahl.
9 ist keine Primzahl.
9 ist eine Primzahl.
10 ist keine Primzahl.
11 ist eine Primzahl.
12 ist keine Primzahl.
13 ist eine Primzahl.
14 ist keine Primzahl.
15 ist keine Primzahl.
15 ist eine Primzahl.
16 ist keine Primzahl.
17 ist eine Primzahl.
18 ist keine Primzahl.
Die returns einfach mit continue auszutauschen ist mehr schlecht als recht, und pures Glück dass es genau bei den ersten 8 Zahlen noch funktioniert.
Ein return bei einer Funktion bricht die Funktion an der Stelle ab, an der das return sich befindet. Ruft man die Funktion in einer Schleife auf fährt es somit direkt mit der nächsten Zahl fort.
Ein continue; ist dazu nur gleichwertig, wenn es sich auf die äußere Schleife bezieht. Nur dann fahre ich nämlich direkt mit der nächsten Zahl fort.
PS: 1 ist keine Primzahl
Wie würdest Du also den oben stehenden Code verändern?
Ich würde eine boolean-Variable einführen, die angibt, ob die Zahl eine Primzahl ist.
Anfangs sollte sie true sein, und sobald ein einziges mal die Zahl restlos teilbar war, soll die Variable auf false gesetzt werden.
Nach der Schleife schaut man sich dann einfach an, ob die Variable false oder true ist.
Aber wenn ich deine Version umändern müsste, dann so:
for (int num = 1; num < 19; num++) {
if(num > 2 && num % 2 == 0) {
System.out.println(num + " ist keine Primzahl.");
continue;
}
int top = (int) Math.sqrt(num) + 1;
boolean continueOuter = false;
for(int i = 3; i < top; i += 2) {
if(num % i == 0){
System.out.println(num + " ist keine Primzahl.");
continueOuter = true;
break;
}
}
if (continueOuter) continue;
System.out.println(num + " ist eine Primzahl.");
}
Meinst Du so?
for(int num = 1; num <= 8; num++) {
boolean isPrime = true;
if(num <= 2 || num % 2 == 0) {
isPrime = false;
}
int top = (int) Math.sqrt(num) + 1;
for(int i = 3; i < top; i += 2) {
if(num % i == 0){
isPrime = false;
}
}
System.out.println(num + " ist " + (isPrime ? "eine" : "keine") + " Primzahl.");
}
num > 2 && num % 2 == 0 muss übrigens zu num <= 2 || num % 2 == 0 abgeändert werden, damit die 1 nicht als Primzahl gilt.
Nicht ganz, wenndann zu
num < 2 || (num > 2 && num % 2 == 0)
Die 2 ist nämlich eine Primzahl, dein Code würde sie jedoch als "keine" bezeichnen :D
0 ist keine Primzahl. num < 2 würde zutreffen und die Aussage wäre war.
Und wenn true, dann wird ausgegeben, dass es keine Primzahl ist, also passt doch
Für kleinere Zahlen ist diese Methode geeignet, allerdings ist der Code bei Code Review für größere Zahlen effizienter. Übrigens: Die innere for-Schleife muss nach isPrime = false; nicht weiterlaufen.