Chillee Geschrieben 23. November 2010 Geschrieben 23. November 2010 Hallo liebe Fachinformatiker.de-User, ich habe folgende Aufgabe: Schreiben Sie ein Programm für die Primfaktorzerlegung einer natürlichen Zahl. Eine Funktion für die Eingabe soll prüfen, ob diese überhaupt zulässig ist (natürliche Zahl) und sonst zur erneuten Eingabe auffordern. Die Generierung/Prüfung von Primzahlen sowie die eigentliche Zerlegung sind in eigenständigen Funktionen zu realisieren. Ich habe dazu nun folgenden Code geschrieben: #include <iostream> // ------- Nebenfunktionen------- // >Eingabe int eingabe (int x) { std::cout<<"Bitte geben sie eine natuerliche Zahl ein: "<<std::endl; std::cin>>x; while (x<1) { std::cout<<"Die eingegebene Zahl ist nicht natuerlich!\nBitte geben sie erneut eine natuerliche Zahl ein: "<<std::endl; std::cin>>x; } return x; } // >Test ob Primzahl int primtest (int p) { int zaehler; if (p < 2) return 0; if (p == 2) return 1; if (p %2 == 0) return 0; for (zaehler = 3; zaehler * zaehler <= p; zaehler = zaehler+2) { if (p % zaehler == 0) return 0; } return 1; } // >Primzahlzerlegung void primzer (int y) { int i; while (y > 1) { i = 2; while ((y%i != 0) && (primtest(i) == 0)) { i = i + 1; } std::cout<<i<<" "<<y<<"\n"; y = y/i; } } // ------ Hauptfunktion ----------- int main () { int n; std::cout<<"Primfaktorzerlegung einer natuerlichen Zahl\n ------------------------- "<<std::endl; eingabe (n); primzer (n); return 0; } Mein Problem ist nun: Ich denke eigentlich müssten die einzelnen Funktionen(Eingabe, Primzahlentest, Primzahlenzerlegung) von der Sache her stimmen, lass mich natürlich auch eines besseren Belehren! Doch wenn ich dieses Programm nun teste, wird der eingegebene Wert von der Eingabefunktion nicht weiter an die zweite Funktion übergeben (so sieht das zumindest aus wenn ich "y" mit ausgeben lasse) und ich komm einfach nicht drauf warum?! Ich hab da jetzt schon eine Ewigkeit dran rumprobiert...doch leider ohne Erfolg! Kann mir hier evtl. jemand weiter helfen? Vielen Dank schonmal, Beste GRüße, Chillee EDIT: Entschuldigt den Fehler in der Überschrift ! Zitieren
Brabax Geschrieben 23. November 2010 Geschrieben 23. November 2010 Ich nehme an, das liegt daran, dass deine 2. Funktion gar keinen Wert erhält, weil du den Return-Wert nicht abspeicherst. Das x was in der Eingabe-Funktion generiert wird ist nur innerhalb der Funktion gültig, also kannst du darauf nicht zugreifen. Du übergibst dein initialisiertes n an die Funktion Eingabe und übergibst danach dein initialisiertes n an die 2. Funktion. Ein einfaches n = Eingabe() sollte dass Problem lösen. Warum übergibst du Eingabe eigentlich eine Variable, wenn es doch erst eine Variable erzeugen soll? lG Zitieren
flashpixx Geschrieben 23. November 2010 Geschrieben 23. November 2010 Schau Dir einmal Primzahltest ? Wikipedia an, den Algorithmus, den Du verwendest, entspricht letztendlich dem "Sieb des Eratosthenes" und ist damit für den Test sehr aufwändig zu berechnen. Zitieren
Chillee Geschrieben 24. November 2010 Autor Geschrieben 24. November 2010 So erstmal vielen Dank für die Antworten. Das Problem mit der Eingabe habe ich nun lösen können ... Ich habe die Eingabefunktion angepasst, weil ich dann zur späteren Stunde nochmal die AuP-Unterlagen gelesen habe und naja da fiel es mir auf. Habe das Ganze nun folgendermaßen gefixt: // >Eingabe int eingabe [B](void)[/B] { [B]int x = 0;[/B] std::cout<<"Bitte geben sie eine natuerliche Zahl ein: "<<std::endl; std::cin>>x; while (x<1) { std::cout<<"Die eingegebene Zahl ist nicht natuerlich!\nBitte geben sie erneut eine natuerliche Zahl ein: "<<std::endl; std::cin>>x; } return x; //und in der main [B]n = eingabe();[/B] } So funktioniert immerhin die Eingabe, jetzt muss ich bloß nach das Problem der Primzahlzerlegung fixen, weil das läuft noch nicht so richtig. Zitieren
Guybrush Threepwood Geschrieben 24. November 2010 Geschrieben 24. November 2010 Zu deinem Ursprünglichen Problem solltest du dir mal Call By Value und Call By Reference anschauen. Zitieren
Chillee Geschrieben 24. November 2010 Autor Geschrieben 24. November 2010 Okay mach ich bei Gelegenheit noch mal ! Danke! Zitieren
Chillee Geschrieben 24. November 2010 Autor Geschrieben 24. November 2010 So denke ich habe die Lösung nun zusammen ! Wenn jemand noch Schwachstellen sieht, dann bitte bis spätestens Freitag posten...Danke! #include <iostream> // ------- Nebenfunktionen------- // >Eingabe int eingabe (void) { int x = 0; std::cout<<"Bitte geben sie eine natuerliche Zahl ein: "; std::cin>>x; while (x<1) { std::cout<<"\nDie eingegebene Zahl ist nicht natuerlich!\nBitte geben sie erneut eine natuerliche Zahl ein: "; std::cin>>x; } return x; } // >Test ob Primzahl bool primtest (int p) { int zaehler; if (p == 2) return 1; if (p %2 == 0) return 0; for (zaehler = 3; zaehler * zaehler <= p; zaehler = zaehler+2) { if (p % zaehler == 0) return 0; } return 1; } // >Primzahlzerlegung int primzer (int y) { int i = 2; while (y > 1) { while ((y%i != 0) || (primtest(i) == 0)) { i = i + 1; } std::cout<<i<<" "; y = y/i; } return 0; } // ------ Hauptfunktion ----------- int main () { int n; int k; std::cout<<"Primfaktorzerlegung einer natuerlichen Zahl\n -------------------------\n "<<std::endl; n = eingabe(); if (n == 1) std::cout<<"\nDie eingegebene Zahl laesst sich nur durch 1 teilen!"<<std::endl; else { k = primtest(n); if (k == 0) { std::cout<<"\nDie Zahl "<<n<<" laesst sich in folgende Primfaktoren zerlegen: "<<std::endl; primzer (n); std::cout<<std::endl; } else { std::cout<<"\n"<<n<<" ist eine Primzahl \nSie ist nur durch: "<<n<<" und 1 teilbar."<<std::endl; } } return 0; } Zitieren
Klotzkopp Geschrieben 24. November 2010 Geschrieben 24. November 2010 int eingabe (void) {Das (void) ist eine Altlast aus C. Schreib einfach int eingabe(). bool primtest (int p) { int zaehler; if (p == 2) return 1; if (p %2 == 0) return 0; for (zaehler = 3; zaehler * zaehler <= p; zaehler = zaehler+2) { if (p % zaehler == 0) return 0; } return 1; }[/code] Wenn deine Funktion bool zurückgibt, dann benutz bitte auch die bool-Literale true und false. Das Verwenden von int für Wahrheitswerte ist auch eine Altlast aus C89. int primzer (int y) {Der Rückgabewert dieser Funktion hat keinen Sinn. Die Funktion gibt immer Null zurück, der Rückgabewert wird auch nicht ausgewertet. Also ändere den Rückgabetyp auf void. i = i + 1; y = y/i;Mehr eine Stilfrage: Das sieht ein wenig nach BASIC aus. Dafür gibt es in C und C++ eigene Operatoren: [code]++i; y/=i; int main () { int n; int k;Und noch eine Altlast aus C89: Du musst Variablen nicht am Blockanfang deklarieren. Deklarier sie da, wo du sie brauchst. Und initialisiere sie. Fehler aufgrund nicht initialisierter Variablen sind schwer zu finden. Die Variablennamen n und k sind auch nicht so toll. Zitieren
Korhil Geschrieben 25. November 2010 Geschrieben 25. November 2010 Ich sehe schon bei der Überprüfung der Eingabe ein Problem: ... Eine Funktion für die Eingabe soll prüfen, ob diese überhaupt zulässig ist (natürliche Zahl) und sonst zur erneuten Eingabe auffordern. ... Für mich klingt das so, als ob du sogar mit Eingaben wie "Hello World" rechnen musst. Diese Eingabe wäre natürlich auch ungültig, würde aber dein Programm derzeit noch überlasten. Oder "4.1", das ist auch eine Zahl, aber halt keine Natürliche. Zitieren
Chillee Geschrieben 25. November 2010 Autor Geschrieben 25. November 2010 Erstmal Dankeschön an Klotzkopp! Ich werde die Anpassungen mal umsetzen ! @ Korhil: Also war die Eingabe von 4.1 betrifft. Das ist nicht so schlimm meinte der Übungsleiter, da durch int eh alle stellen hinter dem Komma abgehackt werden. Was die Eingabe von Hello World betrifft, naja wer lesen kann gibt eig nichts falsches ein ...aber trotzdem würde die mich die Umsetzung beider Fälle interessieren. Kannst du zeigen wie so etwas funktioniert, weil so was haben wir noch nicht gelernt? Zitieren
Korhil Geschrieben 26. November 2010 Geschrieben 26. November 2010 @ Korhil: Also war die Eingabe von 4.1 betrifft. Das ist nicht so schlimm meinte der Übungsleiter, da durch int eh alle stellen hinter dem Komma abgehackt werden. Was die Eingabe von Hello World betrifft, naja wer lesen kann gibt eig nichts falsches ein ...aber trotzdem würde die mich die Umsetzung beider Fälle interessieren. Kannst du zeigen wie so etwas funktioniert, weil so was haben wir noch nicht gelernt? Da ich nur mit C und C# gearbeitet habe, lege ich einfach mal nur die dahinterstehende Idee dar: 1. String einlesen 2. String überprüfen, ob natürliche Zahl 3. Wenn 2. erfüllt, dann umwandeln, sonst weiter mit 1. Ich wäre gerade bei C und seinen Nachfolgern vorsichtig mit einer nachlässigen Werte-Kontrolle. Bei uns sind schon richtige teure Maschinen (7-stelliger Euro-Betrag) ausgefallen, weil einfach nur mal der falsche Typ übergeben wurde. Zitieren
Chillee Geschrieben 26. November 2010 Autor Geschrieben 26. November 2010 Okay...bei Machinen kann es durchaus sinnvoll sein ! Ich denke in diesem Fall ist es nicht gefordert, trotzdem habe ich mir was überlegt und eingebaut, damit wird ein großteil der Falscheingaben aussortiert ... #include <limits> int eingabe () { int x = 0; std::cout<<"Bitte geben sie eine natuerliche Zahl ein: "; while (!(std::cin>>x) || x<1) // irgendwas ging schief { std::cout<<"\nDie eingegebene Zahl ist nicht natuerlich!\nBitte geben sie erneut eine natuerliche Zahl ein: "; if(cin.fail()) // Input konnte nicht konvertiert werden { std::cin.clear(); // Failbit löschen std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n'); // den Rest der Zeile ignorieren und nochmal probieren } } return x; } Ansonsten nochmal vielen Dank an alle, die mir hier weiterhelfen konnten! Ich wünsche ein schönes WE und einen sinnlichen 1. Advent. Beste Grüße, Chillee Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.