Kleine Hilfe



  • Also, das ist meine Aufgabe: Schreiben Sie eine Funktion, welche die Fakultät einer gegebenen Zahl n berechnet, ohne dass Sie eine if -Anweisung, eine switch -Anweisung oder eine Schleife verwenden.

    Und das ist mein code:

    #include<iostream>
    using namespace std;

    int fak(int k)
    {
    int i=1;
    i*=k;
    ((k>1) ? fak(k-1) : 1);
    return i;
    }

    int main()
    {
    int n;
    cout << "Geben Sie n ein : \0";
    cin >> n;
    cout << fak(n);
    cout << endl;

    return 0;
    }

    Wo habe meinen Fehler?



  • Stern schrieb:

    Wo habe meinen Fehler?

    Denkfehler! Du beziehst die Rückgabe der einzelnen Funktionsaufruf nicht in die Berechnung des Ergebnisses mit ein. So würde es gehen:

    #include<iostream>
    using namespace std;
    
    int fak(int k)
    {
    	int i;
    	k > 1 ? i = k * fak(k-1) : i=1;
    	return i;
    }
    
    int main()
    {
    	int n;
    	cout << "Geben Sie n ein : \0";
    	cin >> n;
    	cout << fak(n);
    	cout << endl;
    
    	return 0;
    }
    


  • Hallo,
    Du verwendest den Fragezeichenoperator wie if statt dessen Möglichkeiten zu nutzen. Wenn schon, dann statt

    k > 1 ? i = k * fak(k-1) : i=1;
    

    lieber

    i = k > 1 ? k * fak(k-1) : 1;
    

    oder

    if(k > 1) 
        i = k * fak(k-1)
    else
        i=1;
    


  • moment mal...

    der ? : operator ist doch auch ein if, nur abgekapselt?!?
    der compiler wandelt das doch intern auch in ein if um oder?

    und dennach folgend wie soll die aufgabe dann gelöst werden?!?



  • unsigned long one(int) { return 1; }
    unsigned long fak(int x) {
      unsigned long (*fptrs[])(int) = { one, fak };
    
      return x * fptrs[x > 1](x - 1);
    }
    


  • seldon schrieb:

    unsigned long one(int) { return 1; }
    unsigned long fak(int x) {
      unsigned long (*fptrs[])(int) = { one, fak };
    
      return x * fptrs[x > 1](x - 1);
    }
    

    Hehe, das ist gut. Da wär' ich nicht drauf gekommen.


  • Mod

    Ach, und ich wollte gerade eine Wertetabelle vorschlagen (machbar, denn bereits 21! ist größer als ein 64-Bit unsigned long int), aber seldons Lösung ist schöner.



  • Jetzt noch der Klassiker 🤡

    template<int n>
    class faku
    {
        static unsigned long long int value=n * faku<n-1>::value;
    }
    
    template<>
    class faku<0>
    {
        static unsigned long long int value = 1;
    }
    

    *edit: und ja, das ist eine Funktion, eine Metafunktion 😃

    Skym0sh0 schrieb:

    moment mal...

    der ? : operator ist doch auch ein if, nur abgekapselt?!?
    der compiler wandelt das doch intern auch in ein if um oder?

    und dennach folgend wie soll die aufgabe dann gelöst werden?!?

    Ne, der ? : Operator ist schon was anderes als eine if-Abfrage. Schon semantisch ist das klar, probiere mal eine if-Abfrage in der Initialisierungsliste zu benutzen. Mit dem ? : Operator kein Problem.
    Den Operator kann man auch überall da benutzen, wo man eine RValue hinschreiben darf. Mit einer if bleibt man da schnell auf der Strecke



  • Eine Wertetabelle wäre zwar weniger hübsch, dafür aber schneller.

    Allerdings braucht man die Fakultät jedenfalls in dieser Form in der Praxis eher selten; viele Anfänger sind bei Lottoprogrammen zum ersten Mal mit Integer-Überläufen in Berührung gekommen. Realitätsnäher dürfte Folgendes sein:

    unsigned long one(int, int) { return 1; }
    unsigned long fak_minmax(int n, int k) {
      unsigned long (*fptrs[])(int, int) = { one, fak_minmax };
      return n * fptrs[n - 1 > k](n - 1, k);
    }
    
    unsigned long fak(int n) {
      return fak_minmax(n, 1);
    }
    
    unsigned long bin_coeff(int n, int k) {
      return fak_minmax(n, n - k) / fak(k);
    }
    

    Die etwas merkwürdige Implementation habe ich jetzt nur aus Bequemlichkeit übernommen. Wie weit man damit tatsächlich kommt, kann ich nicht verlässlich einschätzen; ich habe mit Kombinatorik bislang wenig am Hut.

    Ansonsten stellt die Gamma-Funktion eine Verallgemeinerung der Fakultät dar, die für Mathematiker meistens sowieso interessanter sein dürfte.


Anmelden zum Antworten