Primzahl kleiner 3

r1d1

Mitglied
So ich bin's nochmal,

wollte mir als Übung mal ein kleines Programm schreiben, welches mir bei einer eingegebenen Zahl ausgibt, ob es eine Primzahl ist oder nicht. Dazu folgender Code:

Java:
import javax.swing.JOptionPane;

public class Primzahl {

	public static void main(String args[]) {
		String eingabe;
		int x; // Zahl die geprüft werden soll

		eingabe = JOptionPane.showInputDialog("Primzahl ja oder nein?");
		x = Integer.parseInt(eingabe);

		for (int i = (x - 1); i > 1; i--) // ab hier wird x durch immer kleiner werdende
			                              // Zahlen ab (x-1) bis 2 geteilt;
		{
			int proof = x % i;           
			if (proof == 0) // kommt als Restwert nur ein einziges mal 0 heraus erfolgt  
				            // die Ausgabe und das Programm ist beendet;
			{ 
				System.out.println(x + " ist keine Primzahl");
				break;
				
			} else {
				if (i == 2) // wenn i bei 2 angelangt ist war das der letzte Durchlauf
					        // der for-Schleife; x ist dann also eine Primzahl;
				{
					System.out.println(x + " ist eine Primzahl");
				} else {

				}
			}
		}
	}
}

Funktioniert soweit wunderbar, nur wenn ich eine Zahl kleiner 3 eingebe natürlich nicht. Mir ist auch klar, DASS es nicht funktionieren kann, aber ich habe keine andere Idee es umzusetzen. Bräuchte da nen kleinen Denkanstoß 😀
Ich würde auch gerne von den erfahreneren Programmierern wissen, ob der Code stilistisch gesehen in Ordnung ist, ich habe nämlich das Gefühl, dass man das ganze auch kürzer/besser schreiben kann, oder ob sonst irgendwelche Mängel zwecks des Programmierstils auffallen.





Vielleicht können diejenigen ja auch mal einen Blick auf folgendes Programm werfen, welches mir die
Fakultät einer Zahl ausgibt:

Java:
import javax.swing.JOptionPane;

public class Fakultät {

	public static void main(String args[]) {
		methode();
	}

	public static void methode() {
		String eingabe;

		int x;

		eingabe = JOptionPane.showInputDialog("Fakultät von");

		x = Integer.parseInt(eingabe);

		int ergebnis = 1;

		for (int i = 1; i <= x; i++) {
			ergebnis = ergebnis * i;
		}

		System.out.println("Die Fakultät von " + x + " ist: " + ergebnis + ".");

		exit();
	}

	public static void exit() {
		String exitus;
		exitus = JOptionPane.showInputDialog("Exit 1, Continue 2");
		int b = Integer.parseInt(exitus);

		switch (b) {
		case 1:
			break;
		case 2:
			methode();
		default:
			exit();
		}
	}
}

Funktioniert wunderbar, nur der Code kommt mir etwas unbeholfen vor. Ich bin aktuell noch Schüler und habe vor mir programmieren zum Beruf zu machen, und ich denke es ist wichtig und nur von Vorteil wenn man sich von Anfang an einen guten Stil angewöhnt, von dem her bitte ich lieber nochmal um Rückfrage^^
 
Java:
    public static void main(String args[]) {
        String input = JOptionPane.showInputDialog("Primzahl ja oder nein?");
        int x = Integer.parseInt(input);

        // ab hier wird x durch immer kleiner werdende
        // Zahlen ab (x-1) bis 2 geteilt;
        for (int i = (x - 1); i > 1; i--) {
            // kommt als Restwert nur ein einziges mal 0 heraus erfolgt
            // die Ausgabe und das Programm ist beendet;
            if (x % i == 0) {
                System.out.println(x + " ist keine Primzahl");
                return;
            }
        }

        System.out.println(x + " ist eine Primzahl");
    }

ein wenig eingekürzt und vor allem mit kommentaren deutlich besser lesbar.
wechsel nicht zwischen deutsch und englisch (eingabe+beweise oder input+proof)
einrücken ist okay, klammersetzung durchweg bebehalten (kommentare und so)
 
Du solltest du Funktionalität möglichst allgemein halten. Was ich damit meine: Deine beiden Berechnungen sind nur anwendbar, wenn du sie wirklich nur auf der Konsole haben möchtest. Besser wäre es, die Berechnungen in eigenen Operationen mit Rückgabewert zu haben und diese, wenn gewünscht, auf der Konsole ausgeben.
Außerdem solltest du auf mögliche Exceptions achten. Der Anwender könnte etwas anderes als eine Zahl eingeben und dein Programm dadurch zum Absturz bringen (
Code:
NumberFormatException
wird geschmissen).

Zur Primzahlberechnung:
Von der Grundfunktionalität in Ordnung, müsstest zur korrekten Berechnung anfangs überprüfen, ob die Zahl < 2 ist und dann eben false ausgeben. Aus Performancegründen könnte man den Algorithmus noch verbessern, indem man
  1. Die Teiler von klein nach groß durchgeht.
  2. Anfangs durch 2 teilt und dann nur noch durch ungerade Zahlen.
  3. Nur bis zur Quadratwurzel der angegebenen Zahl überprüft (denn wenn es einen Teiler gibt, der größer ist als die Quadratwurzel, so ist das Ergebnis der Division kleiner als die Quadratwurzel, wurde also bereits überprüft).

Es gibt natürlich noch weitaus bessere Algorithmen, aber sowas sollte anfangs genügen:
Java:
import javax.swing.JOptionPane;

public class Primzahl {
	public static void main(String args[]) {
		String eingabe;
		int x; // Zahl die geprüft werden soll
		
		while (true) {
			eingabe = JOptionPane.showInputDialog("Primzahl ja oder nein?");
			try {
				x = Integer.parseInt(eingabe);
				break;
			} catch (NumberFormatException nfe) {
				System.err.println("\"" + eingabe + "\" ist keine Zahl!");
			}
		}
		
		System.out.println(x + " ist " + (isPrime(x) ? "" : "k") + "eine Primzahl.");
	}
	
	public static boolean isPrime(int probablePrime) {
		if (probablePrime < 2)
			return false; // Zahl ist kleiner als 2, also nicht prim.
		if (probablePrime == 2)
			return true; // 2 ist eine Primzahl.
		if (probablePrime % 2 == 0)
			return false; // Alle geraden Zahlen (bis auf die 2, s. o.) sind nicht prim.
		for (int divisor = 3; divisor <= Math.sqrt(probablePrime); divisor += 2) { // Alle ungeraden Teiler bis einschließlich zur Quadratwurzel durchgehen.
			if (probablePrime % divisor == 0)
				return false; // Teiler gefunden, also nicht prim.
		}
		return true; // Keinen Teiler gefunden, also prim.
	}

Zur Fakultät:
Auch hier stimmt die Grundfunktionalität (ist ja nur eine for-Schleife), hier gelten jedoch auch die oben angesprochenen Dinge (Operation auslagern mit Rückgabewert, Exception-Handling).
Dazu kommt hier noch, dass die Fakultät schnell sehr groß wird, weswegen der Wertebereich von
Code:
int
hier leicht erschöpft ist. Stattdessen sollte
Code:
BigInteger
verwendet werden, welches beliebig große Zahlen annehmen kann.

So könnte also bspw. der Algorithmus aussehen:
Java:
	public static BigInteger factorial(int n) {
		BigInteger result = BigInteger.ONE;
		for (int i = 2; i <= n; i++)
			result = result.multiply(BigInteger.valueOf(i));
		return result;
	}

Dann noch allgemeine Tipps zu Code Conventions: Allen Bezeichnern möglichst präzise Namen geben ("methode" und "x" sind dies wohl nicht unbedingt 😉) und Sonderzeichen rauslassen ("Fakultät" -> "Fakultaet").
 

Neue Themen


Zurück
Oben