Primzahlen bis 1000 ausgeben

Siid

Neues Mitglied
Hallo,
ich bringe mir gerade Java bei und habe mir die Aufgabe gestellt, ein Programm alle Primzahlen bis 1000 herausfinden und aufzählen zu lassen:
Java:
public class Primzahlen
{
	public static void main(String[] args)
	{
		int e=2;	//i wird durch e geteilt
		int r=1;	//r für den Rest wenn man eine Primzahl durch e teilt
		System.out.println("Folgendes ist eine Liste aller Primzahlen bis 1000:");
		for(int i=0; i<=1000; i++)	//Schleife zur überprüfung aller Zahlen bis 1000
		{
			while(r!=0 && e<i)	//Schleife zur überprüfung einer einzelnen Zahl
			{
					r=i%e;	//Solange r!=0 i = Primzahl
					e++;		//Hochzählen von dem Teiler e
			}
			if(r!=0)	//Bedingung zur Ausgabe einer Zahl als Primzahl 
			{		//wenn r=0 ist ein Teilungsvorgang aufgegangen => keine Primzahl
				System.out.println(i);
			}
		}
	}
}
Dieses Programm gibt mir jedoch einfach alle Zahlen bis 1000 aus.
Irgendwie schein der neue Wert für "r" nicht den Weg aus der while-Schleife heraus zu finden, sodass für die letzte if-Schleife immer gilt r=1.
Kann das sein?

Grüße
Siid
 
Setze e und r einfach in der äusseren Schleife 🙂 Ansonsten beinhalten sie natürlich immer noch den Wert des letzten Schleifendurchgangs.
 
Ohne Ahnung zu haben, e und r muessen auszerhalb der while Schleide zurueckgesetzt werden damit man fuer jede Zahl einen neuen Zustand verwendet und nicht mit den Werten von der vorherigen Zahl weiterrechnet.

Oder alternativ verschiebt man die Deklaration von r und e in die for Schleife, damit hat man bei jedem Durchlauf einen neuen Zustand.
 
Zuletzt bearbeitet:
Wenn man wissen will, wie ein Algorithmus verändert werden muss um ein Problem zu lösen, dann ist der Ansatz doch immer gleich:

Am Anfang steht immer, dass man erst einmal den Algorithmus selbst verstehen muss. Also was wird denn da gemacht?

Wenn man das aber auf Basis eines gegebenen Codes verstehen will, dann hilft oft ein sogenanntes Refactoring. Das sind dann Maßnahmen, die Code lesbarer machen sollen. Und da gibt es zwei wichtige Praktiken:
a) Umbenennen - wie benennen Bezeichner um. Bei den Variablen i, e und r muss man sich ja fast zusammen reißen, um nicht paar böse Worte zu verlieren.
b) Aufteilen - wieso den Code nicht aufteilen?

Also Umbenennen ... was ist den i? Das ist die zu prüfende zahl, also "zahl" oder "zuPruefendeZahl" oder ähnliches.

r - da könnte man sich anschauen, was man a bekommt, aber da hat man einen Kommentar ... das ist also der "rest".
e - da haben wir auch einen Kommentar, der es uns einfacher macht ... also ist das dann z.B. der "teiler".

Beim Aufteilen ist die Frage: Was machen wir überhaupt? Wir haben eine Schleife über alle Zahlen, eine Prüfung auf Primzahl und dann die Ausgabe... Also können wir es aufteilen ... dann haben wir ein:
Java:
for (int zahl = 2; zahl <= 1000; zahl++) {
    if (isPrime(zahl)) {
        System.out.println("Primzahl: " + zahl);
    }
}

Und die innere Prüfung wird dann auch einfach zu:
Java:
public static boolean isPrime(int zahl){
    int teiler = 2;
    int rest = 1;
    while (rest != 0 && teiler < zahl) {
        rest = zahl % teiler;
        teiler++;
    }
    return rest != 0;
}

Wobei man dann auch schauen muss ... wieso wird Rest auf 1 gesetzt? Und wieso wird erst geprüft und dann etwas berechnet? Das könnte eine do while Schleife besser sein. Dann braucht man auch keine Initialisierung bei der Variable rest mehr.
 
Bei solchen Problemen gehe ich immer mal gerne mit dem Debugger zeilenweise durch, und schaue an welcher Stelle welche Variable nicht mehr das enthält, was ich eigentlich erwarten würde.

Und noch etwas: Es ist immer sehr hilfreich, sein Programm in kleine Methoden aufzuteilen, die beschreiben, welcher Einzelschritt gerade erledigt wird. Deine komplette while-Schleife könntest du in einer Methode bool isNumAPrimeNum(int num){} packen.
Sowas erspart dir die ganzen Kommentare, dafür kannst du deinen Quellcode als eine Art Anleitung lesen. Und, wichtig: mit so einer Programmierweise kannst du relativ komplexe Dinge in mehrere, dafür aber einfachere Dinge zerlegen. Ich lehne mich mal etwas aus dem Fenster und behaupte, daß es dir wahrscheinlich weitaus einfacher fällt, für nur eine einzige Zahl herauszufinden ob es sich um eine Primzahl handelt oder nicht.
 
Edit: Wie ich jetzt erst sehe wurde dir der Tipp bereits gegeben.

Naja, Tipps die man mehrmals bekommt sind vielleicht wirklich nicht so schlecht.
 
Ich habe jetzt eine andere Lösung gefunden. Danke!

for (int i = 1; i <= 100; i++)
{ boolean prim = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) { prim = false; break; } }
if (prim) { System.out.println(i); } }
 
Ich habe jetzt eine andere Lösung gefunden. Danke!
Das entspricht der Lösung, die @KonradN gezeigt hat - nur in komprimierter Form.

Erstmal anständig formatieren:
Java:
for (int i = 1; i <= 100; i++) {
    boolean prim = true; 
    for (int j = 2; j < i; j++) {   
        if (i % j == 0) {
            prim = false;
            break;
         }
    } 
    if (prim) {
        System.out.println(i);
    }
}

Was passiert in der Schleife? Du prüft, ob i eine Primzahl ist und falls ja, gibst Du sie aus. D. h.

Java:
for (int i = 1; i <= 100; i++) {
    if (isPrime(i)) {
        System.out.println(i);
    }
}

Der Code in der Schleife ist dabei einfach in eine andere Methode ausgelagert worden.
Java:
private boolean isPrime(int i) {
    boolean prim = true; 
    for (int j = 2; j < i; j++) {   
        if (i % j == 0) {
            prim = false;
            break;
         }
    } 
    return prim;
}

Das "Ausbrechen" aus der Schleife vermeidet man in der Regel, stattdessen schreibt man
Java:
private boolean isPrime(int i) {
    boolean prim = true; 
    for (int j = 2; j < i && prime; j++) {   
        if (i % j == 0) {
            prim = false;
         }
    } 
    return prim;
}
Der Code von Konrad verwendet einfach eine while- statt eine for-Schleife.

Übrigens: die Prüfung ist äußerst ineffizient, denn wir haben es mit einer Multiplikation zu tun - es macht somit wenig Sinn bis i zu prüfen. Aber das ist ein anderes Thema.
 
Wie muss e und r in der äußeren Schleife gesetzt werden? Arbeite gerade an demselben Problem.
Der große Vorteil bei der Programmierung ist doch, dass man es einfach probieren kann. Wenn die Aussage / Hilfestellung ist:
Setze e und r einfach in der äusseren Schleife 🙂 Ansonsten beinhalten sie natürlich immer noch den Wert des letzten Schleifendurchgangs.
dann kannst Du einfach einmal die Variablen verschieben, sprich die Zeilen 5 und 6 verschiebt man einfach in die äußere Schleife. Und dann probierst Du einfach, ob es geht...

Das aber nur, wenn Du an genau dem Code aus dem ersten Post festhalten willst. Ansonsten gibt es doch genug funktionierenden Code in den einzelnen Antworten, den Du nutzen könntest.

Oder wenn Du fragen hast: Stelle die Fragen so ausführlich, dass wir Dein Problem verstehen und Dir sinnvoll helfen können, Danke.
 

Zurück
Oben