C, Primzahl tester?
Hallo, Also ich mache nun seit 2 Wochen einen Ckurs und wir haben heute eine Aufgabe bekommen einen Primzahl Tester mittles von Schleifen zu coden. Ich komme nach mehreren Stunden immernoch nicht auf irgendwas und habe mir da was im Internet abgeschaut was auch funktioniert jedoch hatten wir die Operationen noch nicht im Kurs behandelt.(ich kenne Sie jedoch aus meinem Vorwissen). Jetzt würde ich mal fragen wie man es einfacher machen könnte und ob mir da jemand aushelfen kann. Ich verstehe auch nicht wie man auf " for(i = 2; i < nummer / 2 && !y; i++)" kommt :/

3 Antworten
i fängt bei 2 an, da man sich durch 1 teilen sparen kann. Das geht ja immer. i geht so lange hoch, bis es größer ist als die Hälfte der Zahl. Das ist offensichtlich, denn wenn ich z. B. 51 überprüfe kann die Zahl ja durch alles ab 26 nicht teilbar sein (ausser 51, was nicht zählt).
Das !y bedeutet y == false. (bzw. y == 0). Wenn das Programm eine Zahl i findet, durch die es die Zahl nummer teilen kann (if(nummer % i == 0)) setzt es dann y = 1. Dadurch hört das Programm bei der nächsten Zahl auf:
Wenn man z. B. 28 schon durch 7 teilen kann muss ich nicht mehr weiter ausprobieren, denn 28 ist dann keine Primzahl.
Das ist schon so ziemlich der Einfachste Weg, das zu machen. Das Programm kann man hier und da umschreiben, aber die Logik bleibt dabei ;). Effizienter kann man es machen (es wird daduch aber "schwieriger").
Solange in y der Wert 0 gespeichert ist ist der Ausdruck !y wahr, hat also keinen Effekt und unterbricht die Schleife nicht. Sobald y in der Schleife mal auf 1 gesetzt wurde ist der Ausdruck aber falsch. Dann ist die Bedingung in der Schleife nicht mehr erfüllt und es wird abgebrochen, denn die Bedingung der for-Schleife ist
/*if*/ ( i < nummer/2 UND !y)
bzw. /*if*/ ( (i < nummer/2) && ( y == 0) )
So ist es einfacher zu verstehen, wenn man der NICHT-Operator nicht so geläufig ist.
Die Variable y merkt sich nur, ob nummer schon mal durch i geteilt werden konnte, denn wenn das so ist, muss man nicht mehr weiter machen.
Heyho vielen Dank. Will dich eigentlich nicht weiter stören aber komm wieder nicht weiter (scheinst ja auch ziemlich viel Plan zu haben). Haben nämlich neue Aufgabe für zuhaus bekommen und ich habe diese auch gelöst jedoch wird diese nicht angenommen. Wir sollen nämlich ein Rechteck(gefüllt mit B also alles die selbe Variable/zahl) mit Höhe 3 und Breit 6 erstellen welches umrahmt ist durch A (selbe Variable/zahl). Und ich hab das so wie in meinem Bild gemacht - https://gyazo.com/c8710828ff233e0e3ed7f0b105458a9a - aber ich soll das so anfangen - breite = 6; höhe = 3; ... code ... - Hab da jetzt irgendwie nicht wirklich einen Ansatz wie man das machen könnte daher wär nett wenn du aushelfen könntest (wenn überhaupt) :D
Soll die Logik stattdessen so? http://pastebin.com/20hXAnf7
Oh man danke für die Antwort. Kann ich fragen was du beruflich machst und wie lange du C schon machst und wie lange du gebraucht hast um das zu schreiben? An sich ist dein Programm aufjedenfall richtig aber unser online tester den wir für Hausaufgaben benutzen gibt einen Fehlercode raus. Das ist btw. die Aufgabe. https://gyazo.com/b1d1af3180d0fe848dfd6db1a24aab9e - Ich versteh auch nicht ganz wie man das interpretieren soll ob man. Meiner Meinung nach ändert das programm die Höhe und Breite und testet ob es dann immernoch ein Rechteck ist aber da hätte ich ja mal null ahnung wie das funktioniert. Vielleicht macht der aber auch größere zahlen da rein sodass dann in der mitte rechts das aus dem Körper rausragt, dann müsste man ja mit Leerzeichen arbeiten aber keine Ahnung um ehrlich zu sein.
Ehm danke für die Hilfe.Hab jetzt das gemacht und das scheint unser system anzunehmen. https://gyazo.com/5fe85abd513cca3bd1e48036017ac0ff
Es hat bestimmt auf die As und Bs als Zeichen bestanden. Ich dachte, das A und B soillte irgendwas gleiches bezeichnen und nicht die Zeichen "A" und "B" ^^
Btw. ich mach nur minimal C++ just for fun. Hab mir ne IDE installiert und n paat minuten geschrieben, habs nicht gestoppt...
Eyo, wennde vielleicht Ahnung davon hast, kannst du ja mal hier rüberschauen https://www.gutefrage.net/frage/c---sieb-des-erathostenes?suggestEdit=1
PS: y wird wie "bool y;" verwendet, falls dir das etwas sagt :). Dass der Datentyp stattdessen "int" ist ist reine Willkür.
Also ich versteh auch nicht ganz wie das mit Bool funktioniert, hatten wir schließlich noch nicht. Hab das aber mal eben versuch halt als bool y zu definieren jedoch tritt da schon ein fehler auf unkown type name also muss ich mir da wahrscheinlich noch eine andere biblio dazuhauen?
Eh okay danke jetzt hab ichs fast. Versteh nur noch nicht wie die letzte Operation funktioniert. if(!y) . . Wieso kann man in dem Falle nicht einfach else schreiben? Das wäre mein Gedanke gewesen das wenn man halt keine Zahl ohne Rest findet das man dann Ja ausgibt.
Das else müsste ja in der For schleife sein. Dann würde bei jedem Durchgang "Nein" in der Konsole ausgegeben. Vor der Schleife steht kein if, darum kann man nach der Schleife kein else benutzen ;)
Die if Abfrage if(!y) soll prüfen, warum die Schleife vorbei ist. Wenn i einfach bis nummer/2 hochgezählt, aber keine Teiler gefunden hat ist y ja immer auf dem Wert 0. Dann ist !y wahr und die Antowort "Ja" wird ausgegeben.
Hat die Schleife voher aber einen Teiler gefunden, so wurde y auf 1 gesetzt. Der Ausdruck !y ist dann falsch und es wird nichts ausgegeben. Das muss es auch nicht, denn er wurde ja schon in der Schleife getan.
Ich würde es so machen:
bool result = false;
if (nummer & 1)
{ result = true; int iMax = (int)round(sqrt(nummer));
for (int ii = 3; ii <= iMax; ii+=2) { if (0 == nummer % ii) { result = false; break; } } printf(result? "ja\n" : "nein\n");}
Nicht ausprobiert, aber es müsste hinhauen. Die Grenze sqrt (Wurzel) von nummer berücksichtigt, dass bei einem Produkt einer Zahl ein Faktor höchstens so groß sein kann wie die Wurzel der Zahl.
Jetzt habe ich die Lust am Ändern verloren, stelle Dir die Formatierung bitte selbst her.
Danke für die Antwort jedoch muss ich sagen als Neuling haut mich solch eine Funktion schon gut um.
Es ist nicht so kompliziert: Das mit der Wurzel habe ich schon erklärt, "Floor" macht eine ganze Zahl draus, (int) wandelt das Fließkommaergebnis auf den Typ int um.
Die Abfrage am Anfang prüft, ob es eine gerade Zahl ist, dann ist es keine Primzahl (Fehler: Hier muss zusätzlich geprüft werden, ob es gerade 2 ist).
Dann werden ab 3 alle Zahlen überprüft, ob sie Teiler von nummer sind (% ist die Modulo-Funktion).
result dient als Marke, ob eine Primzahl vorliegt oder nicht (sollte man eher "istPrimzahl" nennen).
Bin Laie, versteh es aber folgendermaßen:
Du hast eine Zahl (Nummer), diese muss folgende Eigenschaften haben damit die For-Schleife den Integer (i=2) hochzählt:
Die Zahl (Nummer) muss größer sein als der Integer geteilt durch 2 und darf nicht Null sein.
Okay hab ich also genauso aufgefasst jedoch verstehe ich danach das weiter auch nicht (sorry :D) Verstehe nicht ganz den zusammenhang von y in den Funktionen, eher gesagt es irritiert mich. Könnte man nicht statt der letzten If funktion auch else nehmen? Jedoch hab ich dann das problem das die schleife nicht mehr aufhört
Aufjedenfall danke, also das was du schon genannt hattest war mir ja auch schon schlüssig aber mit y hab ich immernoch ein Problem. Also wie gesagt !y ist ja y==false da y ja am anfang aber als y=0 definiert wird heißt es dann doch das !y -> y!=0 ist oder verdreh ich da was?