c# Primzahlen?
Hey liebe Community,
ich hätte da mal eine Frage. Ich habe die Möglichkeit, meinen Code etwas zu verändern. Bisher habe ich mit dem Code geprüft, ob die Eingabe des Benutzers eine Primzahl ist. Wie könnte ich es machen, dass z.B. der Benutzer eine Zahl eingibt (4) und die ersten vier Primzahlen ausgegeben werden?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Primzahlen
{
class Program
{
static bool Primzahl(int primzahl)
{
bool ergebnis = false;
int zähler = 0;
for (int i = 1; i <= primzahl; ++i) // Zahl wird durch Teiler geteilt
{
if (primzahl % i == 0) //Teilung ohne Restwert, dann für 1 zum Zähler hinzufügen
{
zähler = ++zähler;
}
}
if (zähler == 2) //Wenn Zahl nur durch sich und 1 teilbar ist, Ausgabe (Da Zähler auf 2 ist)
{
ergebnis = true;
}
return ergebnis;
}
static void Main(string[] args)
{
Console.Title = "Primzahlen";
StreamWriter sw = new StreamWriter("Primzahlen.txt");
Console.WriteLine("Geben Sie eine Zahl ein");
string eingabe = Console.ReadLine();
sw.WriteLine(eingabe);
sw.Close();
String dateiName = "Primzahlen.txt";
StreamReader reader = null;
int zahl = 0;
try
{
reader = new StreamReader(dateiName);
string zeile = reader.ReadLine();
zahl = Convert.ToInt32(zeile);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (reader != null)
reader.Close();
}
if (Primzahl(zahl))
{
Console.WriteLine("Das ist eine Primzahl");
}
else
{
Console.WriteLine("Keine Primzahl");
}
Console.ReadLine();
}
}
}
Vielen Dank!
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
}
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. ^^)
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 :)
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?
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
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
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.
lässt sich zusammenfassen:
Kritisch, bei einer Quadratzahl (z.B. 9) prüfst Du nur bis 2.