Fakultätsoperator für ein Programm?
-
Will ein Programm schrieben das mit einen Fakultätsoperator rechnen kann. Nur es gibt eine Problem ich weiß nicht wie der Fakultätsoperator rechnet, nur so viel das (7! = 7*6*5*4*3*2*1). Durch die Recherche habe eine Vorstellung wie der Code aussehen könnte:
int fakultaet(int zahl) { int ergebnis = 1; for (int i=2;i<=zahl;i++) { ergebnis = ergebnis * i; } return ergebnis; }Oder
(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))Oder
double fak( double x) { if(x>=1) return 1 return fak( x-1); }
-
#include <iostream> template <int N> class fakultaet { public: enum { value = N * fakultaet<N - 1>::value }; }; template <> class fakultaet<1> { public: enum { value = 1 }; }; int main() { std::cout << fakultaet<4>::value << std::endl; }
-
Und deine Frage?
Das eine ist übrigens kein C++. Lisp?
-
Du kannst in C++ keine Willkürlichen Zeichen als Operatoren definieren. Das geht nur in wenigen Sprachen (z.Bsp. Perl 6).
Deine jetzige Implementation ist relativ langsam und wenn du die Zahlen, die du verwenden willst schon zur Kompillierzeit weisst, würde ich dir Boost.Math.Factorial empfehlen.Im Code steht dann:
#include <boost/math/special_functions/factorials.hpp> int fact10 = boost::math::factorial(10); // oder #include <boost/math/special_functions/factorials.hpp> using namespace boost::math; int fact10 = factorial(10);
-
SeppJ schrieb:
Das eine ist übrigens kein C++. Lisp?
Scheme.
Und das dritte ist syntaktisch falsch und ansonsten eine recht umständliche Art und Weise, return 1; zu schreiben, aber keine Fakultät
Das erste sieht doch ganz gut aus, wo ist das Problem?
-
kurz und knapp:
int fak(int n) { return (n<2) ? n : n * fak(n-1); }rekursive definition und sehr kurz geschrieben

-
TheQ schrieb:
kurz und knapp:
int fak(int n) { return (n<2) ? n : n * fak(n-1); }rekursive definition und sehr kurz geschrieben

und falsch.
-
Danke für die Hilfe, jetzt kann ich es im den Code infügen.
-
Bashar schrieb:
TheQ schrieb:
kurz und knapp:
int fak(int n) { return (n<2) ? n : n * fak(n-1); }rekursive definition und sehr kurz geschrieben

und falsch.
wo denn?
-
TheQ schrieb:
Bashar schrieb:
TheQ schrieb:
kurz und knapp:
int fak(int n) { return (n<2) ? n : n * fak(n-1); }rekursive definition und sehr kurz geschrieben

und falsch.
wo denn?
Gib mal 0 ein.
-
ok, mal laut wikipedia die definition angeschaut und verbessert.
int fak(int n) { return (n==0) ? 1 : n * fak(n-1); }
-
sieht richtig aus.
-
Ist aber immer noch ziemlich lahm. Für Fakultäten gibt es keinen guten Grund zur Rekursion zu greifen. Schließlich gibt es keinerlei Verzweigungen im Ablauf.
-
Bei dir kann man -1 eingeben und das Resultat ist sicher komisch.
Deshalb:// 1. Variante unsigned fak(unsigned n) { return n?n*fak(n-1):1; } // 2. Variante int fak(int n) { return n<2?1:n*fak(n-1); } // 1 bei -1 ist zwar komisch, aber verständlich
-
Des halb habe ich auch aus Performancegründen zum TMP gegriffen ^^
-
Ja sicher, TMP: überhaupt nicht rekursiv und sehr schnell und praxisbezogen:
int i; std::cin >> i; std::cout << fakultaet<i>() << std::endl;Da verwende ich doch lieber Boost, weil für vordefinierte Werte Fakultäten vom Compiler berechnen zu lassen ist doch eher unüblich (und ausserdem musst du die Funktion sehr oft aufrufen, um die dafür zusätzlich benötigte Compilezeit wieder reinzuholen).
-
int fak(unsigned n) { unsigned result=1; for (unsigned i=1; i<=n; ++n) result*=i; return result; }Sieht zwar weniger schick aus, aber lasst das mal gegen die Rekursionsfunktion rennen.
edit: <= natürlich. Alte Gewohnheit

-
SeppJ schrieb:
int fak(unsigned n) { unsigned result=1; for (unsigned i=1; i<=n; ++n) result*=i; return result; }Sieht zwar weniger schick aus, aber lasst das mal gegen die Rekursionsfunktion rennen.
edit: <= natürlich. Alte Gewohnheit

Ist aber immernoch falsch

-
hmmmmm,..
x>(2^13) kommt doch so oder so ein überlauf,... da beschwer ich mich doch nicht über die performance,... geschweige das das double noch net mal darstellen kann,..
greetz
-
HighLigerBiMBam schrieb:
Ist aber immernoch falsch

template<typename Type> Type Facul(Type x) { if(x<0) return 0; Type f=1; while(x>1) f*=x--; return(f); }So kann's aussehen. Von rekursiven Aufrufen kann ich nur abraten, bei solchen Spielfunktonen noch akzeptabel, ist bei einigen anderen Algorithmen wie z.B. Floodfill nicht angebracht.