c# Primzahlen?

2 Antworten

Okay, die Antwort an sich gabs ja schon von BrauchJzHilfe, aber da wären noch ein paar Kleinigkeiten:

1) Wozu das StreamWriter-Gedöns? Du hast doch die Eingabe schon in der Variablen eingabe.

2) Wozu die ganzen using-Direktiven? Wenn du den unnötigen StreamWriter/StreamReader-Kram rausnimmst bleibt using System; als einzige noch nötige übrig.

3) Dein Primzahlentest funktioniert zwar, ist aber furchtbar ineffizient. Es reicht wenn du die Schleife nur bis zur Quadratwurzel der Zahl durchlaufen lässt.

Eine weit effizientere Methode um zu testen ob es sich um eine Primzahl handelt oder nicht wäre z.B. diese:

static bool IsPrime(int number){
    if(number < 2) return false; //Keine Primzahl ist kleiner als 2
    if(number==2) return true; //2 ist die einzige gerade Primzahl
    if((number&1)==0) return false; //Keine gerade Zahl ungleich 2 ist eine Primzahl
    int limit = (int)Math.Ceiling(Math.Sqrt(number)); //Die Quadratwurzel des Kanidaten auf die nächsthöhere ganze Zahl gerundet
    for(int divisior = 3; divisior < limit; ++divisior){ //Durch 0 zu teilen wäre Schwachsinn, auch 2 als möglicher Teiler ist raus, fangen wir also mit der 3 an
        if(number%divisior==0) return false; //Wenn hierbei 0 rauskommt, dann gibt es (mindestens) einen dritten Teiler, also keine Primzahl
    }
    return true; //Zusammengesetzte Zahlen sind ausgeschlossen, also Primzahl
}
Mikkey  05.02.2019, 19:48
if(number==2) return true; //2 ist die einzige gerade Primzahl
if((number&1)==0) return false; //Keine gerade Zahl ungleich 2 ist eine Primzahl

lässt sich zusammenfassen:

if ((number&1)==0) return (number==2);
int limit = (int)Math.Ceiling(Math.Sqrt(number));

Kritisch, bei einer Quadratzahl (z.B. 9) prüfst Du nur bis 2.

3
Isendrak  05.02.2019, 20:11
@Mikkey
lässt sich zusammenfassen:

Aber dann ists nicht mehr so schön übersichtlich zu kommentieren. ^^

Kritisch, bei einer Quadratzahl (z.B. 9) prüfst Du nur bis 2.

Kritisch wirds erst eine Zeile später, aber da machst einfach aus dem < ein <=, dann passts. (Verdammte Quadratzahlen! So etwas können wir bei Primzahlentests nicht gebrauchen. Am besten wir bauen eine Mauer und die Quadratzahlen werden sie bezahlen! Covfefe! Covfefe! ^^)

Aber ja, das mit den Quadratzahlen hab ich tatsächlich komplett übersehen. (Wieso gibts hier eigentlich den "Danke sagen"-Button nur für Antworten? Gäbs ihn auch für Kommentare, hätt ich ihn geklickt. ^^)

0
Mikkey  05.02.2019, 20:17
@Isendrak

Um den Vorteil zu halten sollte dann noch Ceiling durch Floor ersetzt werden.

1
FurkanAbi29 
Fragesteller
 06.02.2019, 13:02

Du hast eigentlich auf alles geantwortet, außer auf meine eigentliche Frage. Ich musste es mit einer bool-Funktion machen und auf die Eingabe aus einer Datei zugreifen. Trotzdem danke für deine Antwort :)

0
Isendrak  06.02.2019, 13:25
@FurkanAbi29

Naja, die "eigentliche Frage" wurde ja wie gesagt schon von BrauchJzHilfe beantwortet. Meine Antwort ist eigentlich mehr ein "großer Kommentar". ^^

Allerdings stellt sich mir immer noch die Frage nach dem Sinn dahinter, die Eingabe zunächst in eine Datei zu speichern und direkt danach die selbe Eingabe wieder auszulesen und dann zu verwenden.

Könnte es evtl. sein, dass sich die Aufgabenstellung eigentlich darauf bezog, dass der Benutzer den Namen einer Datei eingeben soll, aus der dann die Zahlen ausgelesen werden?

1

Du könntest eine Schleife durchgehen lassen (von 1 - ...) und immer prüfen, ob es ne Primzahl ist. Ist dies der Fall, erhöst du einen Counter.

Ist dieser 4, beendest du die Schleife

BrauchJzHilfe  05.02.2019, 18:17

Noch ein paar andere Dinge:

    zähler = ++zähler; 
    

    wird zu

    zähler++;
    

    oder

    ++zähler;
    
    • Vermeide Umlaute als Namen
    • Wenn du den Typ der Variablen angibst, solltest du das in Kleinbuchstaben tun. Machst du i.d.R. auch, aber siehe Zeile 73
    2
    regex9  06.02.2019, 01:12
    @BrauchJzHilfe
    Wenn du den Typ der Variablen angibst, solltest du das in Kleinbuchstaben tun. 

    In dem Fall zwar richtig, aber pauschal gesehen falsch. Nur wenn ein Alias zu dem gegebenen Typ existiert, hat man die Wahl, das sollte so eindeutig formuliert werden. Üblicherweise entscheidet man sich dann auch für den Alias, denn er ist oft kürzer und spart womöglich auch eine using-Direktive.

    Bei Aufrufen statischer Methoden/Properties/Felder hingegen gibt es eine Konvention, nach der an dieser Stelle dann wieder der Klassenname verwendet wird (s. MSDN-Dokumentation).

    Beispiel:

    string someString = String.Empty;
    

    Ich persönlich kann dem jedoch nichts abgewinnen und nutze wenn nur das Alias.

    1