Zum Inhalt springen

Änfängerproblem mit recht "schöner" Aufgabe


Empfohlene Beiträge

Geschrieben

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 :D !

Geschrieben

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

Geschrieben

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.

Geschrieben

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;

}

Geschrieben
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.

Geschrieben

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.

Geschrieben

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 :D...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?

Geschrieben
@ 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 :D...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.

Geschrieben

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

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...