web-dev-qa-db-fra.com

Comment trouver une factorielle?

Comment puis-je écrire un programme pour trouver la factorielle d'un nombre naturel?

32
Kraken

Cela fonctionnera pour le factoriel (bien qu’un très petit sous-ensemble) d’entiers positifs:

unsigned long factorial(unsigned long f)
{
    if ( f == 0 ) 
        return 1;
    return(f * factorial(f - 1));
}

printf("%i", factorial(5));

En raison de la nature de votre problème (et du niveau que vous avez admis), cette solution repose davantage sur le concept de résolution de ce problème que sur une fonction qui sera utilisée dans le prochain "Moteur de permutation".

36
Kyle Rozendo

Ceci calcule les factorielles d'entiers non négatifs [*] jusqu'à ULONG_MAX, qui auront tellement de chiffres qu'il est peu probable que votre machine puisse stocker beaucoup plus, même si elle a le temps de les calculer. Utilise la bibliothèque GNU multi-précision, avec laquelle vous devez créer un lien.

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>

void factorial(mpz_t result, unsigned long input) {
    mpz_set_ui(result, 1);
    while (input > 1) {
        mpz_mul_ui(result, result, input--);
    }
}

int main() {
    mpz_t fact;
    unsigned long input = 0;
    char *buf;

    mpz_init(fact);
    scanf("%lu", &input);
    factorial(fact, input);

    buf = malloc(mpz_sizeinbase(fact, 10) + 1);
    assert(buf);
    mpz_get_str(buf, 10, fact);
    printf("%s\n", buf);

    free(buf);
    mpz_clear(fact);
}

Exemple de sortie:

$ make factorial CFLAGS="-L/bin/ -lcyggmp-3 -pedantic" -B && ./factorial
cc -L/bin/ -lcyggmp-3 -pedantic    factorial.c   -o factorial
100
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

[*] Si vous voulez dire autre chose par "numéro", vous devrez être plus précis. Je ne connais aucun autre nombre pour lequel la factorielle est définie, malgré les vaillants efforts de Pascal pour étendre le domaine en utilisant la fonction Gamma.

27
Steve Jessop

Pourquoi le faire en C quand vous pouvez le faire en Haskell :

Étudiant de première année Haskell

fac n = if n == 0 
           then 1
           else n * fac (n-1)

Sophomore Haskell, programmeur au MIT (A étudié Scheme à titre d'étudiant de première année)

fac = (\(n) ->
        (if ((==) n 0)
            then 1
            else ((*) n (fac ((-) n 1)))))

Programmeur Junior Haskell (Joueur débutant de Peano)

fac  0    =  1
fac (n+1) = (n+1) * fac n

Un autre programmeur junior de Haskell (Lire que les motifs n + k sont «une partie dégoûtante de Haskell» 1 Et ont rejoint le mouvement «Ban n + k motifs» [2])

fac 0 = 1
fac n = n * fac (n-1)

Senior programmeur Haskell (A voté pour Nixon Buchanan Bush - "se penche à droite")

fac n = foldr (*) 1 [1..n]

Un autre programmeur expérimenté de Haskell .__ (vota pour McGovern Biafra Nader - «penche à gauche»)

fac n = foldl (*) 1 [1..n]

Encore un autre programmeur senior de Haskell (Penché tellement à droite qu’il revint encore à gauche!)

-- using foldr to simulate foldl

fac n = foldr (\x g n -> g (x*n)) id [1..n] 1

Mémo du programmeur Haskell (Prend Ginkgo Biloba tous les jours)

facs = scanl (*) 1 [1..]

fac n = facs !! n

Pointless (ahem) Programmeur Haskell «sans points» (Étudié à Oxford)

fac = foldr (*) 1 . enumFromTo 1

Programmeur itératif Haskell (Ancien programmeur Pascal)

fac n = result (for init next done)
        where init = (0,1)
              next   (i,m) = (i+1, m * (i+1))
              done   (i,_) = i==n
              result (_,m) = m

for i n d = until d n i

Programmeur Haskell à une ligne itératif (Ancien programmeur APL et C)

fac n = snd (until ((>n) . fst) (\(i,m) -> (i+1, i*m)) (1,1))

Programmateur accumulateur Haskell (Atteignant un point culminant rapide)

facAcc a 0 = a
facAcc a n = facAcc (n*a) (n-1)

fac = facAcc 1

Programmeur Haskell de passage à la suite (Il a élevé des lapins dans les premières années, puis a déménagé dans le New Jersey)

facCps k 0 = k 1
facCps k n = facCps (k . (n *)) (n-1)

fac = facCps id

Programmeur de Boy Scout Haskell (Aime faire des nœuds; il est toujours "respectueux", il Appartient à l'Église du Point le moins fixe [8])

y f = f (y f)

fac = y (\f n -> if (n==0) then 1 else n * f (n-1))

Programmeur combinatoire Haskell (Évite les variables, sinon l’obscurcissement; Tout ce currying n’est qu’une phase, bien qu’il gêne rarement)

s f g x = f x (g x)

k x y   = x

b f g x = f (g x)

c f g x = f x g

y f     = f (y f)

cond p f g x = if p x then f x else g x

fac  = y (b (cond ((==) 0) (k 1)) (b (s (*)) (c b pred)))

Programmeur Haskell à codage de liste .__ (préfère compter en unaire)

arb = ()    -- "undefined" is also a good RHS, as is "arb" :)

listenc n = replicate n arb
listprj f = length . f . listenc

listprod xs ys = [ i (x,y) | x<-xs, y<-ys ]
                 where i _ = arb

facl []         = listenc  1
facl n@(_:pred) = listprod n (facl pred)

fac = listprj facl

Programmeur d'interprétation Haskell (Jamais "rencontré une langue" qu'il n'a pas aimé)

-- a dynamically-typed term language

data Term = Occ Var
          | Use Prim
          | Lit Integer
          | App Term Term
          | Abs Var  Term
          | Rec Var  Term

type Var  = String
type Prim = String


-- a domain of values, including functions

data Value = Num  Integer
           | Bool Bool
           | Fun (Value -> Value)

instance Show Value where
  show (Num  n) = show n
  show (Bool b) = show b
  show (Fun  _) = ""

prjFun (Fun f) = f
prjFun  _      = error "bad function value"

prjNum (Num n) = n
prjNum  _      = error "bad numeric value"

prjBool (Bool b) = b
prjBool  _       = error "bad boolean value"

binOp inj f = Fun (\i -> (Fun (\j -> inj (f (prjNum i) (prjNum j)))))


-- environments mapping variables to values

type Env = [(Var, Value)]

getval x env =  case lookup x env of
                  Just v  -> v
                  Nothing -> error ("no value for " ++ x)


-- an environment-based evaluation function

eval env (Occ x) = getval x env
eval env (Use c) = getval c prims
eval env (Lit k) = Num k
eval env (App m n) = prjFun (eval env m) (eval env n)
eval env (Abs x m) = Fun  (\v -> eval ((x,v) : env) m)
eval env (Rec x m) = f where f = eval ((x,f) : env) m


-- a (fixed) "environment" of language primitives

times = binOp Num  (*)
minus = binOp Num  (-)
equal = binOp Bool (==)
cond  = Fun (\b -> Fun (\x -> Fun (\y -> if (prjBool b) then x else y)))

prims = [ ("*", times), ("-", minus), ("==", equal), ("if", cond) ]


-- a term representing factorial and a "wrapper" for evaluation

facTerm = Rec "f" (Abs "n" 
              (App (App (App (Use "if")
                   (App (App (Use "==") (Occ "n")) (Lit 0))) (Lit 1))
                   (App (App (Use "*")  (Occ "n"))
                        (App (Occ "f")  
                             (App (App (Use "-") (Occ "n")) (Lit 1))))))

fac n = prjNum (eval [] (App facTerm (Lit n)))

Static Haskell Programmer (Il le fait avec classe, il a ce fundep Jones! Après "Le plaisir avec les dépendances fonctionnelles" de Thomas Hallgren [7])

-- static Peano constructors and numerals

data Zero
data Succ n

type One   = Succ Zero
type Two   = Succ One
type Three = Succ Two
type Four  = Succ Three


-- dynamic representatives for static Peanos

zero  = undefined :: Zero
one   = undefined :: One
two   = undefined :: Two
three = undefined :: Three
four  = undefined :: Four


-- addition, a la Prolog

class Add a b c | a b -> c where
  add :: a -> b -> c

instance              Add  Zero    b  b
instance Add a b c => Add (Succ a) b (Succ c)


-- multiplication, a la Prolog

class Mul a b c | a b -> c where
  mul :: a -> b -> c

instance                           Mul  Zero    b Zero
instance (Mul a b c, Add b c d) => Mul (Succ a) b d


-- factorial, a la Prolog

class Fac a b | a -> b where
  fac :: a -> b

instance                                Fac  Zero    One
instance (Fac n k, Mul (Succ n) k m) => Fac (Succ n) m

-- try, for "instance" (sorry):
-- 
--     :t fac four

Programmeur débutant de Haskell pour les études supérieures (L’enseignement supérieur tend à libérer les préoccupations insignifiantes Concernant, par exemple, l’efficacité des nombres entiers basés sur le matériel)

-- the natural numbers, a la Peano

data Nat = Zero | Succ Nat


-- iteration and some applications

iter z s  Zero    = z
iter z s (Succ n) = s (iter z s n)

plus n = iter n     Succ
mult n = iter Zero (plus n)


-- primitive recursion

primrec z s  Zero    = z
primrec z s (Succ n) = s n (primrec z s n)


-- two versions of factorial

fac  = snd . iter (one, one) (\(a,b) -> (Succ a, mult a b))
fac' = primrec one (mult . Succ)


-- for convenience and testing (try e.g. "fac five")

int = iter 0 (1+)

instance Show Nat where
  show = show . int

(zero : one : two : three : four : five : _) = iterate Succ Zero


Origamist Haskell programmer
(always starts out with the “basic Bird fold”)

-- (curried, list) fold and an application

fold c n []     = n
fold c n (x:xs) = c x (fold c n xs)

prod = fold (*) 1


-- (curried, boolean-based, list) unfold and an application

unfold p f g x = 
  if p x 
     then [] 
     else f x : unfold p f g (g x)

downfrom = unfold (==0) id pred


-- hylomorphisms, as-is or "unfolded" (ouch! sorry ...)

refold  c n p f g   = fold c n . unfold p f g

refold' c n p f g x = 
  if p x 
     then n 
     else c (f x) (refold' c n p f g (g x))


-- several versions of factorial, all (extensionally) equivalent

fac   = prod . downfrom
fac'  = refold  (*) 1 (==0) id pred
fac'' = refold' (*) 1 (==0) id pred

Programmeur Haskell à tendance cartésienne (Préfère la cuisine grecque, évite les épices indiennes épicées; Inspiré de «Sorting Morphisms» de Lex Augusteijn [3])

-- (product-based, list) catamorphisms and an application

cata (n,c) []     = n
cata (n,c) (x:xs) = c (x, cata (n,c) xs)

mult = uncurry (*)
prod = cata (1, mult)


-- (co-product-based, list) anamorphisms and an application

ana f = either (const []) (cons . pair (id, ana f)) . f

cons = uncurry (:)

downfrom = ana uncount

uncount 0 = Left  ()
uncount n = Right (n, n-1)


-- two variations on list hylomorphisms

hylo  f  g    = cata g . ana f

hylo' f (n,c) = either (const n) (c . pair (id, hylo' f (c,n))) . f

pair (f,g) (x,y) = (f x, g y)


-- several versions of factorial, all (extensionally) equivalent

fac   = prod . downfrom
fac'  = hylo  uncount (1, mult)
fac'' = hylo' uncount (1, mult)

Doctorat Programmeur Haskell (A mangé tellement de bananes que ses yeux se sont troublés, maintenant il a besoin de nouvelles lentilles!)

-- explicit type recursion based on functors

newtype Mu f = Mu (f (Mu f))  deriving Show

in      x  = Mu x
out (Mu x) = x


-- cata- and ana-morphisms, now for *arbitrary* (regular) base functors

cata phi = phi . fmap (cata phi) . out
ana  psi = in  . fmap (ana  psi) . psi


-- base functor and data type for natural numbers,
-- using a curried elimination operator

data N b = Zero | Succ b  deriving Show

instance Functor N where
  fmap f = nelim Zero (Succ . f)

nelim z s  Zero    = z
nelim z s (Succ n) = s n

type Nat = Mu N


-- conversion to internal numbers, conveniences and applications

int = cata (nelim 0 (1+))

instance Show Nat where
  show = show . int

zero = in   Zero
suck = in . Succ       -- pardon my "French" (Prelude conflict)

plus n = cata (nelim n     suck   )
mult n = cata (nelim zero (plus n))


-- base functor and data type for lists

data L a b = Nil | Cons a b  deriving Show

instance Functor (L a) where
  fmap f = lelim Nil (\a b -> Cons a (f b))

lelim n c  Nil       = n
lelim n c (Cons a b) = c a b

type List a = Mu (L a)


-- conversion to internal lists, conveniences and applications

list = cata (lelim [] (:))

instance Show a => Show (List a) where
  show = show . list

prod = cata (lelim (suck zero) mult)

upto = ana (nelim Nil (diag (Cons . suck)) . out)

diag f x = f x x

fac = prod . upto


Post-doc Haskell programmer
(from Uustalu, Vene and Pardo’s “Recursion Schemes from Comonads” [4])

-- explicit type recursion with functors and catamorphisms

newtype Mu f = In (f (Mu f))

unIn (In x) = x

cata phi = phi . fmap (cata phi) . unIn


-- base functor and data type for natural numbers,
-- using locally-defined "eliminators"

data N c = Z | S c

instance Functor N where
  fmap g  Z    = Z
  fmap g (S x) = S (g x)

type Nat = Mu N

zero   = In  Z
suck n = In (S n)

add m = cata phi where
  phi  Z    = m
  phi (S f) = suck f

mult m = cata phi where
  phi  Z    = zero
  phi (S f) = add m f


-- explicit products and their functorial action

data Prod e c = Pair c e

outl (Pair x y) = x
outr (Pair x y) = y

fork f g x = Pair (f x) (g x)

instance Functor (Prod e) where
  fmap g = fork (g . outl) outr


-- comonads, the categorical "opposite" of monads

class Functor n => Comonad n where
  extr :: n a -> a
  dupl :: n a -> n (n a)

instance Comonad (Prod e) where
  extr = outl
  dupl = fork id outr


-- generalized catamorphisms, zygomorphisms and paramorphisms

gcata :: (Functor f, Comonad n) =>
           (forall a. f (n a) -> n (f a))
             -> (f (n c) -> c) -> Mu f -> c

gcata dist phi = extr . cata (fmap phi . dist . fmap dupl)

zygo chi = gcata (fork (fmap outl) (chi . fmap outr))

para :: Functor f => (f (Prod (Mu f) c) -> c) -> Mu f -> c
para = zygo In


-- factorial, the *hard* way!

fac = para phi where
  phi  Z             = suck zero
  phi (S (Pair f n)) = mult f (suck n)


-- for convenience and testing

int = cata phi where
  phi  Z    = 0
  phi (S f) = 1 + f

instance Show (Mu N) where
  show = show . int

Professeur titulaire (Enseignement de Haskell aux étudiants de première année)

fac n = product [1..n]
21
fortran

Grâce à Christoph, une solution C99 qui fonctionne pour pas mal de "nombres":

#include <math.h>
#include <stdio.h>

double fact(double x)
{
  return tgamma(x+1.);
}

int main()
{
  printf("%f %f\n", fact(3.0), fact(5.0));
  return 0;
}

produit 6.000000 120.000000

18
Pascal Cuoq

Pour n grand, vous pouvez rencontrer quelques problèmes et vous pouvez utiliser l'approximation de Stirling:

Lequel est: 

alt text

12
ast4

Si votre objectif principal est une fonction de recherche intéressante:

int facorial(int a) {
   int b = 1, c, d, e;
   a--;
   for (c = a; c > 0; c--)
   for (d = b; d > 0; d--)
   for (e = c; e > 0; e--)
   b++;
   return b;
}

(Non recommandé comme algorithme pour une utilisation réelle.)

9
sth

En C99 (ou Java), j'écrirais la fonction factorielle de manière itérative comme ceci:

int factorial(int n)
{
    int result = 1;
    for (int i = 2; i <= n; i++)
    {
        result *= i;
    }
    return result;
}
  • C n’est pas un langage fonctionnel et vous ne pouvez pas vous fier à l’optimisation des appels ultérieurs. Donc, n'utilisez pas la récursivité en C (ou Java) à moins que vous n'en ayez besoin.

  • Le fait que factorial soit souvent utilisé comme premier exemple de récursivité ne signifie pas nécessairement que vous avez besoin de récursivité pour le calculer.

  • Cela débordera silencieusement si n est trop grand, comme c'est le cas dans C (et Java).

  • Si les nombres que int peut représenter sont trop petits pour les factorielles que vous voulez calculer, choisissez un autre type de nombre. long long s'il doit être légèrement plus grand, float ou double si n n'est pas trop grand et que l'imprécision ne vous gêne pas, ou de grands entiers si vous voulez les valeurs exactes de facteurs très grands.

7
starblue

une version queue-récursive:

long factorial(long n)
{
    return tr_fact(n, 1);
}
static long tr_fact(long n, long result)
{
    if(n==1)
        return result;
    else
        return tr_fact(n-1, n*result);
}
7
user290462

Voici un programme C qui utilise l'implémentation BIGNUM d'OPENSSL et qui, par conséquent, n'est pas particulièrement utile pour les étudiants. (Bien sûr, accepter un BIGNUM comme paramètre d'entrée est fou, mais il est utile pour démontrer l'interaction entre les BIGNUM).

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <openssl/crypto.h>
#include <openssl/bn.h>

BIGNUM *factorial(const BIGNUM *num)
{
    BIGNUM *count = BN_new();
    BIGNUM *fact = NULL;
    BN_CTX *ctx = NULL;

    BN_one(count);
    if( BN_cmp(num, BN_value_one()) <= 0 )
    {
        return count;
    }

    ctx = BN_CTX_new();
    fact = BN_dup(num);
    BN_sub(count, fact, BN_value_one());
    while( BN_cmp(count, BN_value_one()) > 0 )
    {
        BN_mul(fact, count, fact, ctx);
        BN_sub(count, count, BN_value_one());
    }

    BN_CTX_free(ctx);
    BN_free(count);

    return fact;
}

Ce programme de test montre comment créer un nombre à saisir et comment utiliser la valeur de retour:

int main(int argc, char *argv[])
{
    const char *test_cases[] =
    {
        "0", "1",
        "1", "1",
        "4", "24",
        "15", "1307674368000",
        "30", "265252859812191058636308480000000",
        "56", "710998587804863451854045647463724949736497978881168458687447040000000000000",
        NULL, NULL
    };
    int index = 0;
    BIGNUM *bn = NULL;
    BIGNUM *fact = NULL;
    char *result_str = NULL;

    for( index = 0; test_cases[index] != NULL; index += 2 )
    {
        BN_dec2bn(&bn, test_cases[index]);

        fact = factorial(bn);

        result_str = BN_bn2dec(fact);
        printf("%3s: %s\n", test_cases[index], result_str);
        assert(strcmp(result_str, test_cases[index + 1]) == 0);

        OPENSSL_free(result_str);
        BN_free(fact);
        BN_free(bn);
        bn = NULL;
    }

    return 0;
}

Compilé avec gcc:

gcc factorial.c -o factorial -g -lcrypto
5
indiv
int factorial(int n){
    return n <= 1 ? 1 : n * factorial(n-1);
}
5
Orr Matarasso
#Newbie programmer
def factorial(x):
    if x == 0:
        return 1
    else:
        return x * factorial(x - 1)
print factorial(6)


#First year programmer, studied Pascal
def factorial(x):
    result = 1
    i = 2
    while i <= x:
        result = result * i
        i = i + 1
    return result
print factorial(6)


#First year programmer, studied C
def fact(x): #{
    result = i = 1;
    while (i <= x): #{
        result *= i;
        i += 1;
    #}
    return result;
#}
print(fact(6))


#First year programmer, SICP
@tailcall
def fact(x, acc=1):
    if (x > 1): return (fact((x - 1), (acc * x)))
    else:       return acc
print(fact(6))


#First year programmer, Python
def Factorial(x):
    res = 1
    for i in xrange(2, x + 1):
        res *= i
    return res
print Factorial(6)


#Lazy Python programmer
def fact(x):
    return x > 1 and x * fact(x - 1) or 1
print fact(6)


#Lazier Python programmer
f = lambda x: x and x * f(x - 1) or 1
print f(6)


#Python expert programmer
import operator as op
import functional as f
fact = lambda x: f.foldl(op.mul, 1, xrange(2, x + 1))
print fact(6)


#Python hacker
import sys
@tailcall
def fact(x, acc=1):
    if x: return fact(x.__sub__(1), acc.__mul__(x))
    return acc
sys.stdout.write(str(fact(6)) + '\n')


#EXPERT PROGRAMMER
import c_math
fact = c_math.fact
print fact(6)


#ENGLISH EXPERT PROGRAMMER
import c_maths
fact = c_maths.fact
print fact(6)


#Web designer
def factorial(x):
    #-------------------------------------------------
    #--- Code snippet from The Math Vault          ---
    #--- Calculate factorial (C) Arthur Smith 1999 ---
    #-------------------------------------------------
    result = str(1)
    i = 1 #Thanks Adam
    while i <= x:
        #result = result * i  #It's faster to use *=
        #result = str(result * result + i)
           #result = int(result *= i) #??????
        result str(int(result) * i)
        #result = int(str(result) * i)
        i = i + 1
    return result
print factorial(6)


#Unix programmer
import os
def fact(x):
    os.system('factorial ' + str(x))
fact(6)


#Windows programmer
NULL = None
def CalculateAndPrintFactorialEx(dwNumber,
                                 hOutputDevice,
                                 lpLparam,
                                 lpWparam,
                                 lpsscSecurity,
                                 *dwReserved):
    if lpsscSecurity != NULL:
        return NULL #Not implemented
    dwResult = dwCounter = 1
    while dwCounter <= dwNumber:
        dwResult *= dwCounter
        dwCounter += 1
    hOutputDevice.write(str(dwResult))
    hOutputDevice.write('\n')
    return 1
import sys
CalculateAndPrintFactorialEx(6, sys.stdout, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)


#Enterprise programmer
def new(cls, *args, **kwargs):
    return cls(*args, **kwargs)

class Number(object):
    pass

class IntegralNumber(int, Number):
    def toInt(self):
        return new (int, self)

class InternalBase(object):
    def __init__(self, base):
        self.base = base.toInt()

    def getBase(self):
        return new (IntegralNumber, self.base)

class MathematicsSystem(object):
    def __init__(self, ibase):
        Abstract

    @classmethod
    def getInstance(cls, ibase):
        try:
            cls.__instance
        except AttributeError:
            cls.__instance = new (cls, ibase)
        return cls.__instance

class StandardMathematicsSystem(MathematicsSystem):
    def __init__(self, ibase):
        if ibase.getBase() != new (IntegralNumber, 2):
            raise NotImplementedError
        self.base = ibase.getBase()

    def calculateFactorial(self, target):
        result = new (IntegralNumber, 1)
        i = new (IntegralNumber, 2)
        while i <= target:
            result = result * i
            i = i + new (IntegralNumber, 1)
        return result

print StandardMathematicsSystem.getInstance(new (InternalBase, new (IntegralNumber, 2))).calculateFactorial(new (IntegralNumber, 6))

source http://Gist.github.com/25049

4
Anantha Kumaran

Vous utilisez le code suivant pour le faire.

#include    <stdio.h>
#include    <stdlib.h>

int main()
{
   int x, number, fac;
   fac = 1;
   printf("Enter a number:\n");
   scanf("%d",&number);

   if(number<0)
   {
      printf("Factorial not defined for negative numbers.\n");
      exit(0);
   }

   for(x = 1; x <= number; x++)
   {
      if (number >= 0)
         fac = fac * x;
      else
         fac=1;
   }

   printf("%d! = %d\n", number, fac);
} 
3
vivek

Je ne pense pas que je l'emploierais dans la plupart des cas, mais une pratique bien connue et de moins en moins utilisée consiste à disposer d'un tableau de recherche. Si nous ne travaillons qu'avec des types intégrés, la mémoire atteinte est minime.

Juste une autre approche, pour rendre le poster conscient d’une technique différente. De nombreuses solutions récursives peuvent également être mémorisées dans lesquelles une table de recherche est remplie lorsque l'algorithme est exécuté, ce qui réduit considérablement le coût des futurs appels (un peu comme le principe de la compilation .NET JIT).

3
Mr. Boy

Pour les grands nombres, vous pouvez probablement vous en tirer avec une solution approximative, que tgamma vous donne (n! = Gamma (n + 1)) à partir de math.h. Si vous voulez des nombres encore plus grands, ils ne rentreront pas dans un double. Vous devez donc utiliser lgamma (journal naturel de la fonction gamma).

Si vous travaillez quelque part sans un C99 math.h complet, vous pouvez facilement faire ce genre de chose vous-même:

double logfactorial(int n) {
  double fac = 0.0;
  for ( ; n>1 ; n--) fac += log(fac);
  return fac;
}
3
Rex Kerr

Solution simple:

unsigned int factorial(unsigned int n)
{
   return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}
2
Yuliia Ashomok

Le plus simple et efficace est de résumer les logarhitms. Si vous utilisez Log10, vous obtenez de la puissance et un exposant.

Pseudocode

r=0
for i form 1 to n
    r=r+log(i)/log(10)

print "result is:", 10^(r-floor(r)) ,"*10^" , floor(r)

Vous devrez peut-être ajouter le code pour que la partie entière n'augmente pas trop et diminue donc la précision, mais le résultat sera correct même pour les très grandes factorielles.

2
Luka Rahne

Nous devons commencer à partir de 1 jusqu'à la limite spécifiée, par exemple n. Commencer à partir de 1*2*3...*n.

En c, je l'écris en tant que fonction.

main()
{
 int n;
 scanf("%d",&n);
 printf("%ld",fact(n));
}

long int fact(int n)
{
 long int facto=1;
 int i; 
for(i=1;i<=n;i++)
 {
  facto=facto*i;
 }
 return facto;
}
2
Raj

Exemple en C (C a été marqué, donc je suppose que c'est ce que vous voulez) en utilisant la récursivité

unsigned long factorial(unsigned long f)
{
        if (f) return(f * factorial(f - 1));
        return 1;
}

printf("%lu", factorial(5));
2
S.Hoekstra

Je le ferais avec une table de calcul pré-calculée, comme l'a dit John. Ce serait plus rapide à calculer qu'une solution itérative ou récursive. Cela dépend de la rapidité avec laquelle n! croît, car le plus grand n! vous pouvez calculer sans déborder un unsigned long long (valeur maximale de 18 446 744 073 709 551 615) n’est que 20!, de sorte que vous n’avez besoin que d’un tableau de 21 éléments. Voici à quoi cela ressemblerait en c:

long long factorial (int n) {
    long long f[22] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000, 51090942171709440000};
    return f[n]; 
}

Voir par vous-même!

0
Alexander
**I used this code for Factorial:**

#include<stdio.h>
int main(){
  int i=1,f=1,n;

  printf("\n\nEnter a number: ");
  scanf("%d",&n);
  while(i<=n){
      f=f*i;
      i++;
  }
  printf("Factorial of is: %d",f);
  getch();
}
0
Omar Faruk