C# Primzahlentest

moby07

Lieutenant
Registriert
Sep. 2007
Beiträge
901
Kann mir wer noch bitte ab Zeile "while (e == "unbekannt")" genau schreiben, was dort passiert? Die markierten Zeilen verstehe ich ja, nur der Rest ist mir sprachtechnisch ein Rätsel.

Console.WriteLine("Bitte geben Sie eine Zahl ein. Primzahl?");
int a = Convert.ToInt32(Console.ReadLine());
int b = 2; //potentieller Teiler
string e = "unbekannt"; // ist Primzahl?

if (a == 1) e = "ja";

while (e == "unbekannt")
{
for (int i = 2; i < a; i++)
{
if (b >= a) e = "eine";
if ((a % b) == 0) e = "keine";


b++;
}
};

Console.WriteLine("{0} ist {1} Primzahl!", a, e);
 
Zuletzt bearbeitet von einem Moderator:
Du musst nur bis i == a/2 laufen lassen.

Alles was größer ist als die Hälfte, ist eh nicht mehr ganzzahlig teilbar, spart dafür aber die Hälfte an Rechenzeit :)


edit: oh, war gar nicht die Frage :D

Naja, es wird halt von 2 ausgehend durch alle ganzen Zahlen geteilt, und zwar bis man an der eingegebenen Zahl angekommen ist.

Falls bis dahin keine Zahl gefunden wurde, mit der man die eingegebene Zahl ohne Rest teilen kann, ist es eine Primzahl.

Im String e wird das Ergebnis gespeichert.
 
Zuletzt bearbeitet:
">=" ist größer-gleich, "%" ist Modulo.

Der Rest sind if-Abfragen sowie while- und for-Schleifen, teils auch in diesem Thread beschrieben.
 
Alles was größer ist als die Hälfte, ist eh nicht mehr ganzzahlig teilbar, spart dafür aber die Hälfte an Rechenzeit
genau genommen reicht es, bis zur wurzel der zahl zu gehen. aber das war kaum die antwort auf seine frage^^.

wenn der TE aber das markierte versteht, dann ist mir nicht klar, wo das problem liegt. falls 1 eingegeben wird, ist es eine primzahl. falls eine andere zahl eingegeben wird, geht man jede zahl von 2 bis a durch, ob sie ein teiler ist. falls ja, ist es keine primzahl.
 
Aber wie kann ich

while (e == "unbekannt")
und{
for (int i = 2; i < a; i++)

erklären bzw. was sagt man dazu?

Edit: Und warum heißt es gerade "b++"?
 
Zuletzt bearbeitet:
Abgesehen davon, funktioniert das Programm überhaupt?
Bzw. kann man in C# Strings mit "==" vergleichen?

Jedenfalls gibt es eine Compare-Methode.
 
Hat zwar nichts mit deiner Frage zu tun aber wenn man 3 eingibt kommt raus, dass 3 keine Primzahl ist was nicht stimmt.
 
Okay, das ist mir jetzt auch gerade erst aufgefallen.

Nun, wenn mein Text nicht mehr reperabel ist, was wäre die einfachste Lösung (mit Schleifen)?
 
powerfx schrieb:
Abgesehen davon, funktioniert das Programm überhaupt?
Bzw. kann man in C# Strings mit "==" vergleichen?

wie auch in java geht das, ist aber unschön.

Nun, wenn mein Text nicht mehr reperabel ist, was wäre die einfachste Lösung (mit Schleifen)?
naja, so ein einfaches codebeispiel gibt es garantiert zu tausenden im netz.
wie wärs mit google?
 
Zuletzt bearbeitet:
maxFrisch schrieb:
genau genommen reicht es, bis zur wurzel der zahl zu gehen.
Oha, das stimmt. Danke sehr :)


moby07 schrieb:
Edit: Und warum heißt es gerade "b++"?

Postinkrement, addieren + 1 nach Auslesen der Variablen.

Nichts für ungut, aber das ist elementarstes Grundwissen. Ich empfehle an der Stelle, sich etwas tiefer mit dem Thema zu befassen.
 
Nein, das ist mir klar was es bedeutet. Aber warum heißt es gerade b++ und nicht a++? Oder übersehe ich da gerade was?
 
moby07 schrieb:
Nein, das ist mir klar was es bedeutet. Aber warum heißt es gerade b++ und nicht a++? Oder übersehe ich da gerade was?
Da "b" der nächste zu prüfende Teiler ist und "a" deine Eingabe. Du willst ja nur den nächsten Teiler prüfen und nicht deine Eingabe ändern.

maxFrisch schrieb:
Bzw. kann man in C# Strings mit "==" vergleichen?
wie auch in java geht das, ist aber unschön.
In Java vergleichst du mit "==" nur die Referenzen der String-Objekte, d. h. wenn du "String a = "Hello" und "String b = "Hello" hast gilt (im Allgemeinen) "a == b == false". Das ist zumindest für mich nicht wirklich intuitiv.

In C# darf man Strings sehr wohl mit "==" vergleichen, da der "=="-Operator für Strings überladen ist. Hier gilt "a == b == true".
Das ist auch nicht unschön, sondern sogar so gewollt. Nur wenn man z. B. Groß- und Kleinschreibung ignorieren will, muss man "Equals" benutzen.
(Immer "Equals" zu benutzen ist natürlich auch nicht falsch, da "==" auch nur "Equals" aufruft, aber i. d. R. nutzt man "==".)
 
Zuletzt bearbeitet: (On-Topic hinzugefügt. ;))
In Java vergleichst du mit "==" nur die Referenzen der String-Objekte, d. h. wenn du "String a = "Hello" und "String b = "Hello" hast gilt (im Allgemeinen) "a == b == false". Das ist zumindest für mich nicht wirklich intuitiv.

also ich weiß ja nicht woher du dein wissen beziehst, aber kannst ja gerne mal in java
String a = hallo;
String b = hallo;
if(a==b)
{
System.out.println("Der Cadillac Man weiß nicht wovon er redet");
}
tippen und schauen was passiert :rolleyes:.

und c# hat das gleiche problem wie java. "==" ist und bleibt unschön und sollte vermieden werden, wenn man sauberen code haben will.

Nur wenn man z. B. Groß- und Kleinschreibung ignorieren will, muss man "Equals" benutzen.
lol grad erst gesehen. das ist ja mal richtig spektakulär. man haut zwei unterschiedliche strings in .equals() und bekommt raus, dass sie gleich sind? was sich microsoft dabei wohl gedacht hat?

man man.
 
Zuletzt bearbeitet:
maxFrisch schrieb:
also ich weiß ja nicht woher du dein wissen beziehst, aber kannst ja gerne mal in java
String a = hallo;
String b = hallo;
if(a==b)
{
System.out.println("Der Cadillac Man weiß nicht wovon er redet");
}
tippen und schauen was passiert :rolleyes:.
Das liegt aber an der JVM, die für identische String-Literale das selbe Objekt verwendet:
String literals and, more generally, strings that are the values of constant expressions are "interned" so as to share unique instances, using the method String.intern.

Quelle: Java Virtual Machine Specification, Chapter 2.3. Hervorhebung von mir.
Ich geb zu, dass das Beispiel aus genau diesem Grund schlecht gewählt war.
"==" vergleicht aber trotzdem nur die Referenzen. :D



maxFrisch schrieb:
und c# hat das gleiche problem wie java. "==" ist und bleibt unschön und sollte vermieden werden, wenn man sauberen code haben will.
C# hat eben nicht das gleiche Problem, da "==" die Werte der Strings vergleicht.
Was man verwendet ist (für ordiniale Vergleiche) absolut egal, da der "=="-Operator intern auch nur "String.Equals" aufruft.
Im .NET-Bereich sind Stringvergleiche mit "==" definitiv gebräuchlicher. Auch "offizieller" Microsoft-Best-Practise-Code sowie die MSDN-Samples verwenden hauptsächlich "==".

EDIT:
maxFrisch schrieb:
man haut zwei unterschiedliche strings in .equals() und bekommt raus, dass sie gleich sind? was sich microsoft dabei wohl gedacht hat?
Wenn man die richtige Überladung benutzt schon, sonst natürlich nicht:
Code:
string a = "Hallo";
string b = "hallo";

bool x = a.Equals(b); // False
bool y = a.Equals(b, StringComparison.OrdinalIgnoreCase); // True
Da ist für mich nichts missverständliches (voodoo-mäßiges) dran. Du kannst natürlich auch "Compare" benutzen, wenn dir dann wohler ist. ;)
 
Zuletzt bearbeitet:
maxFrisch schrieb:
also ich weiß ja nicht woher du dein wissen beziehst, aber kannst ja gerne mal in java
String a = hallo;
String b = hallo;
if(a==b)
{
System.out.println("Der Cadillac Man weiß nicht wovon er redet");
}
tippen und schauen was passiert :rolleyes:.
Naja, als erstes wird es nicht kompilieren, da "hallo" nicht zu einer Variablen aufgelöst werden kann.
Dann änderst du den betroffenen Teil zu
Code:
String a = "hallo";
String b = "hallo";
womit es dann tatsächlich funktioniert, aber nur weil die Objekte hier gleich sind.
Ändern wird den Code ein bisschen in
Code:
String a = new String("hallo");
String b = new String("hallo");

if (a.equals(b))
	System.out.println("Der Cadillac Man hatte recht");

if (a == b)
	System.out.println("Der Cadillac Man weiß nicht wovon er redet");
um, sieht es schon anders aus.


*Edit: Ich entschuldige mich übrigens fürs OT, womit ich angefangen habe (dachte MS hätte Java konsequenter kopiert... ;))
 
Zuletzt bearbeitet:
ja die anführungsstriche habe ich bei der ide meiner wahl (forumsoftware) doch glatt nicht dazugemacht :rolleyes:.
das man durch anlegen eines neuen objektes das pooling verhindert ist mir auch klar. deswegen ist meine aussage aber trotzdem richtig und der zitierte teil falsch.

naja egal. ich denke das eigentliche problem des threads ist eh geklärt ;).
 
Zuletzt bearbeitet:
Ich bin mal so frei den Code etwas zu formatieren:

Code:
Console.WriteLine("Bitte geben Sie eine Zahl ein. Primzahl?");
int a = Convert.ToInt32(Console.ReadLine());
int b = 2; //potentieller Teiler
string e = "unbekannt"; // ist Primzahl?

if (a == 1) e = "ja";

while (e == "unbekannt") {
    for (int i = 2; i < a; i++) {
        if (b >= a) 
            e = "eine";
        if ((a % b) == 0) 
            e = "keine";

        b++;
    }
};

Console.WriteLine("{0} ist {1} Primzahl!", a, e);

Erstmal ein paar kleinigkeiten zum Stil:

1. Das Semikolon am ende von Zeile 17 (nach der "}" von while) dürfte überflüssig sein.
2. Warum überhaupt eine While-Schleife, wenn du eigentlich nur prüfen willst ob e im Teil darüber schon gesetzt wurde?
Code:
if(e == "unbekannt") {
...
}
wäre doch deutlich besser.
3. Du benutzt eine for-Schleife (mit i als Zählvariable), warum "schleifst" du dann noch eine weitere Variable b mit, die du ebenfalls in jedem Durchlauf um 1 erhöhst? Hier kannst du doch das b++ (in Zeile 15) weglassen, und überall wo du jetzt mit "b" vergleichst, vergleichst du stattdessen mit i.
4. Du hast einen kleinen, aber doch gravierenden Denkfehler in deiner for-Schleife. Wie bereits gesagt gibt er dir für die Zahl 3 beispielsweise ein falsches ergebnis aus. Das liegt daran, dass beim Durchlauf mit i (oder b) = 3 die Schleife wie folgt ausgewertet wird:
Code:
a = 3
b = 3
e = "unbekannt"

if (3 >= 3) e = "eine"    // soweit eigentlich richtig
//der Rest wird aber weiter ausgewertet, und e mit dem falschen überschrieben
if ((3 % 3) == 0) e = "keine" // das wollen wir nicht
Was du also willst ist, dass die For-Schleife beendet wird, sobald ein Ergebnis gefunden wurde (Primzahl oder nicht). Dafür gibt es in c#, wie in anderen programmiersprachen auch, das "break" um die aktuelle Schleife zu beenden. Damit kannst du, wenn es eine Primzahl ist oder sicher keine ist, die Schleife verlassen und dein Ergebnis bleibt unverändert.

Zusätzlich würde ich stark davon abraten, einen String zu benutzen um den Zustand bzw einen boolschen Wert zu speichern. Wie bereits mehrfach hier schon angedeutet wurde, haben Strings teilweise recht eigenwillige Verhalten wenn man sie miteinander vergleicht. Ich würde eher empfehlen entweder ein "bool" zu nehmen, das true ist, wenn es sich um eine Primzahl handelt, und false wenn nicht. Alternativ geht auch ein int mit 0 als undefiniert, 1 als ja und 2 als nein (oder -1 undefiniert, 1 = ja, 0 = nein), da sich bool bzw int viel leichter und zuverlässiger vergleichen lassen.
Du hättest dann zwar eine kleine Redundanz bei der Ausgabe, aber die ist zu verkraften denke ich (Beispiel für den fall e ist int und -1 ungültig, 0 = keine primzahl, 1 = primzahl):
Code:
if (e > 0) {
Console.WriteLine("{0} ist eine Primzahl!", a);
} else {
Console.WriteLine("{0} ist keine Primzahl!", a);
}
 
Zuletzt bearbeitet:
Zurück
Oben