Primfaktorzerlegung in C mit Schnittstelle



  • Ich habe folgende Rahmenbedingungen:

    - keine globalen Variablen
    - innerhalb der Funktion keine Ein- und Ausgabe erlaubt
    - die Kommunikation muss über die Schnittstelle erfolgen

    Also das Programm mit der Primfaktorzerlegung muss in folgende Schnittstelle gepackt werden:
    int primfaktor ( int );

    Die Funktion gibt bei jedem Funktionsaufruf mit einem Parameter n den nächsten Primfaktor von n
    zurück (also numerisch aufsteigend, mehrfach vorkommende Faktoren werden auch mehrfach zurückgegeben). Sobald sich der Wert der übergebenen Zahl n ändert beginnt die Funktion wieder von vorne mit der Primfaktorzerlegung. Hat die Funktion alle Primfaktoren für ein n errechnet und zurückgegegeben so gibt sie (bis zum Aufruf mit einem neuen Wert n) immer -1 zurück.

    Im Fehlerfall gibt die Funktion immer den Wert -2 zurück.

    Mir fehlt jetzt eigentlich nur noch das mit -1 und mit -2 aber wie bau ich das noch ein?

    #include <stdio.h>
    #include <math.h>
    
    int primfaktor(int n)
    {
         int i;
    
      while (n%2 == 0)
      {
      printf("%d ", 2);
      n = n/2;
      }
    
      for (i = 3; i <= sqrt(n); i = i+2)
      {
    
      while (n%i == 0)
      {
      printf("%d ", i);
      n = n/i;
      }
      }
    
      if (n > 2)
      printf ("%d ", n);
    }
    int main()
    {
      int pf;
    
      while ((pf = primfaktor (12))> 1)
      printf ("%d\n", pf);
      while ((pf = primfaktor(7)) > 1)
      printf ("%d\n", pf);
      printf ("%d\n" , primfaktor (1));
      system("PAUSE");
      return 0;
    
    }
    

    Die Ausgabe sollte so aussehen:
    2
    2
    3
    7
    -2 usw.



  • - innerhalb der Funktion keine Ein- und Ausgabe erlaubt

    Was ist printf() deiner Meinung nach denn?



  • Deine while-schleifem können nicht richtig Funktionieren, da deine Funktion nichts zurück gibt.

    Der Compiler sollte das mit einer Warnung anmeckern.
    Wenn nicht, ändere den Warnlevel so, dass er warnt.



  • Eine Ausgabe aber wenn ich die rauslösche funktioniert gar nichts mehr 😞



  • Hinweis wegen Warnlevel beachten. GCC: -Wall -Wextra

    Für die eigentliche Funktion informiere dich mal über das Schlüsselwort static. Imho liegt da die Lösung.



  • Soll ichs stattdessen mit einer if-Anweisung schreiben?
    Der main-Teil ist vorgegeben



  • Bumblebe3 schrieb:

    Eine Ausgabe aber wenn ich die rauslösche funktioniert gar nichts mehr 😞

    Die Aufgabe gibt doch alles vor.

    Was funktioniert denn nicht?



  • DirkB schrieb:

    Die Aufgabe gibt doch alles vor.

    Was funktioniert denn nicht?

    Irgendwie alles 😞 Wenn ich printf in der Schnittstelle rausnehme geht gar nichts mehr bleibt es drin bekomme wenigestens die Ausgabe hin! Ich weiß einfach nicht wie ich das anders anstellen soll. Dazu kommt noch, dass bei einer Fehlermeldung -2 ausgegeben werden soll!



  • Du musst dir den inneren Zustand der Funktion dauerhaft merken.

    Der Inhalt von i und n darf nach dem Verlassen der Funktion nicht verloren gehen.

    Wegen -1 und -2 (und auch den Primfaktoren): Kannst du etwas mit dem Befehl return anfangen?



  • return ist mir ein Begriff. Habe mir auch schon gedacht in Zeile 26 das Ganze so zu schreiben if(n<2) return -2; aber das bringt mich auch nicht weiter



  • Du hast kein Grundverständnis darüber was du gemacht hast und was du machen sollst.
    Deine Funktion soll den nächsten Primfaktor liefern, d.h. selbst keine Änderungen am Wert vornehmen;
    deswegen musst du die Teilung des Wertes durch den (errechneten) Faktor selbst vornehmen, d.h. im aufrufenden Kontext.
    Du versuchst, beides innerhalb der Funktion zu machen, das ist grundsätzlich falsch gemäß Aufgabenstellung.

    int primfaktor(int n)
    {
      int i;
    
      if( n<1 )
      	return -2;
    
      if( n==1 )
      	return -1;
    
      if (n%2 == 0)
      {
        return 2;
      }
    
      for (i = 3; i <= sqrt(n); i = i+2)
      {
        if (n%i == 0)
      	{
      		return i;
      	}
      }
    
      return n;
    }
    
    int main()
    {
      int r, pf=65535;
    
      while ((r = primfaktor (pf))> 1)
      {
      	printf("%d\n",r);
      	pf=pf/r;
      }
      return 0;
    }
    

    http://ideone.com/4cj3Vm



  • Die main-Funktion war vorgegeben 🙂



  • Das mag sein, aber da kannst du mal sehen, was für Müll dein Lehrer fabriziert.
    Seine main-'Vorgaben' passen nicht zur Aufgabenstellung, der Mann hat keine Ahnung.



  • Ja tut mir echt leid dafür aber wenn es nicht nach den Vorgaben gemacht wird, wird es als "nicht bestanden" gewertet 😕 Ich probiere ja echt schon ne Weile daran rum, dass genau die Ausgabe rauskommt.



  • Das mag sein, aber da kannst du mal sehen, was für Müll dein Lehrer fabriziert.Seine main-'Vorgaben' passen nicht zur Aufgabenstellung, der Mann hat keine Ahnung.

    Sorry, das halte ich für falsch. Es sollte mittels static-Variablen sehr wohl möglich sein sich den inneren Zustand der Funktion zwischen zwei Aufrufen zu merken. Imho passt die main().



  • 42**2 schrieb:

    Das mag sein, aber da kannst du mal sehen, was für Müll dein Lehrer fabriziert.Seine main-'Vorgaben' passen nicht zur Aufgabenstellung, der Mann hat keine Ahnung.

    Sorry, das halte ich für falsch. Es sollte mittels static-Variablen sehr wohl möglich sein sich den inneren Zustand der Funktion zwischen zwei Aufrufen zu merken. Imho passt die main().

    Und wie sollte das Ganze dann aussehen? Damit habe ich nämlich keine Ahnung 😞



  • Ich hab mittlerweile eine offensichtlich funktionierende Lösung erstellt, möchte diese aber nicht einfach so posten...

    Wie schon gesagt die Funktion muss sich zwischen den Aufrufen ihren inneren Zustand (=was war das n vom letzten Aufruf, wie weit ist dieses n schon zerlegt bzw. was ist noch davon übrig und wo steht i) merken. Das geht mit static. Sagt dir dieses Wort etwas? Wenn Nein dann nachgucken!

    Genauer gesagt:

    was war das n vom letzten Aufruf
    Wenn ich primfaktor(42); aufrufe dann ist das 42. Wenn ich danach primfaktor(11) schreibe ist das 11.

    wie weit ist dieses n schon zerlegt bzw. was ist noch davon übrig
    Beim ersten Aufruf mit Parameter 42 gibt die Funktion 2 zurück und von der 42 ist noch 42/2=21 übrig. Beim nächsten Aufruf kommt 3 zurück und es bleibt noch 21/3=7. usw...

    und wo steht i
    Sagen wir mal wir rufen die Funktion mit der Zahl 5*5*7=175 auf. Beim ersten Aufruf kommt 5 zurück und genau da bleibt n stehen, so dass beim nächsten Aufruf die zweite 5 zurück kommt. Dann geht es weiter bis zur sieben und da ist dann in diesem Fall auch Schluss. Man kann i auch wieder bei 3 anfangen lassen, dann dauert die Berechnung halt "länger" (auch wenn man das bei 42 oder 175 nicht merken dürfte).



  • KORREKTUR:

    Beim ersten Aufruf kommt 5 zurück und genau da bleibt i stehen,



  • static sagt mir was 😋



  • Nur Deppen benutzen (lokal) static.


Anmelden zum Antworten