webentwicklung-frage-antwort-db.com.de

Wie finde ich eine Fakultät?

Wie kann ich ein Programm schreiben, um die Fakultät einer natürlichen Zahl zu finden?

32
Kraken

Dies funktioniert für die Fakultät (wenn auch eine sehr kleine Teilmenge) von positiven ganzen Zahlen:

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

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

Aufgrund der Art Ihres Problems (und des von Ihnen bekannten Niveaus) basiert diese Lösung eher auf dem Konzept der Lösung dieses Problems als auf einer Funktion, die in der nächsten "Permutation Engine" verwendet wird.

36
Kyle Rozendo

Hiermit werden Fakultäten für nicht negative ganze Zahlen [*] bis zu ULONG_MAX berechnet, die so viele Ziffern enthalten, dass es unwahrscheinlich ist, dass Ihr Computer eine ganze Menge mehr speichern kann, selbst wenn er Zeit hat, diese zu berechnen. Verwendet die GNU Multiple Precision Library, mit der Sie eine Verknüpfung herstellen müssen.

#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);
}

Beispielausgabe:

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

[*] Wenn du etwas anderes als "Zahl" meinst, musst du genauer sein. Mir sind keine anderen Zahlen bekannt, für die die Fakultät definiert ist, obwohl Pascal sich bemüht hat, die Domäne durch Verwendung der Gamma-Funktion zu erweitern.

27
Steve Jessop

Warum es in C machen, wenn man in Haskell machen kann :

Freshman Haskell-Programmierer

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

Sophomore Haskell-Programmierer am MIT .__ (studierte als Neuling)

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

Junior Haskell Programmierer (Anfänger Peano-Spieler)

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

Ein weiterer Junior-Haskell-Programmierer (Lesen Sie, dass n + k Muster "ein ekelhafter Teil von Haskell" 1 Sind und sich der "Ban n + k Muster" -Bewegung [2] anschließen.)

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

Senior Haskell-Programmierer .__ (gewählt für Nixon Buchanan Bush - "lehnt sich nach rechts")

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

Ein anderer hochrangiger Haskell-Programmierer. (Gewählt für McGovern Biafra Nader - "lehnt sich nach links")

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

Noch ein älterer Haskell-Programmierer. (Lehnte sich so weit nach rechts, dass er wieder links war!)

-- using foldr to simulate foldl

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

Protokollierung des Programmierers von Haskell (Nimmt täglich Ginkgo Biloba)

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

fac n = facs !! n

Sinnloser (ähm) "Punkte-freier" Haskell-Programmierer (Studierte in Oxford)

fac = foldr (*) 1 . enumFromTo 1

Iterativer Haskell-Programmierer (Früherer Pascal-Programmierer)

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

Iterativer Einzeiler-Haskell-Programmierer (Früherer APL- und C-Programmierer)

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

Haskell-Programmierer akkumulieren (Aufbau auf einen schnellen Höhepunkt)

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

fac = facAcc 1

Weitergabe-Haskell-Programmierer (RABBITS in frühen Jahren angehoben, dann nach New Jersey gezogen)

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

fac = facCps id

Pfadfinder-Haskell-Programmierer .__ (mag Knoten binden; immer "ehrfürchtig"; er Gehört zur Kirche des kleinsten Fixpunkts [8])

y f = f (y f)

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

Kombinatorischer Haskell-Programmierer (Lehnt Variablen ab, wenn nicht Verschleierung; Das ganze Currying ist nur eine Phase, obwohl es selten behindert)

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)))

List-Encoding-Haskell-Programmierer

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 [email protected](_:pred) = listprod n (facl pred)

fac = listprj facl

Interpretierender Programmierer von Haskell ("Traf nie eine Sprache", die er nicht mochte)

-- 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)))

Statischer Haskell-Programmierer (Er macht es mit dem Unterricht, er hat den Grundstein Jones! Nach Thomas Hallgrens "Spaß mit funktionalen Abhängigkeiten" [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

Beginn des Haskell-Programmierers für Hochschulabsolventen. (Die Absolventenausbildung befreit in der Regel von unbedeutenden Problemen .__ über beispielsweise die Effizienz hardwarebasierter Ganzzahlen).

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

Haskell-Programmierer, kartesisch veranlagt. (Bevorzugt griechisches Essen, vermeidet das scharfe indische Zeug; Inspiriert von Lex Augusteijns „Sorting Morphisms“ [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)

Ph.D. Haskell-Programmierer (Hat so viele Bananen gegessen, dass seine Augen herauskamen, jetzt braucht er neue Linsen!)

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

Tenured Professor .__ (unterrichtet Haskell Neulingen)

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

Dank an Christoph, eine C99-Lösung, die für einige "Zahlen" funktioniert:

#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;
}

produziert 6.000000 120.000000

18
Pascal Cuoq

Bei großen n können Sie auf einige Probleme stoßen und Sie können die Annäherung von Stirling verwenden:

Welches ist: 

alt text

12
ast4

Wenn Ihr Hauptziel eine interessant aussehende Funktion ist:

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;
}

(Nicht als Algorithmus für den tatsächlichen Einsatz empfohlen.)

9
sth

In C99 (oder Java) würde ich die Faktorfunktion iterativ folgendermaßen schreiben:

int factorial(int n)
{
    int result = 1;
    for (int i = 2; i <= n; i++)
    {
        result *= i;
    }
    return result;
}
  • C ist keine funktionale Sprache und Sie können sich nicht auf die Optimierung des Anrufs verlassen. Verwenden Sie also keine Rekursion in C (oder Java), es sei denn, Sie müssen dies tun.

  • Nur weil Factorial oft als erstes Beispiel für Rekursion verwendet wird, bedeutet dies nicht, dass Sie Rekursion benötigen, um es zu berechnen.

  • Dies wird automatisch überlaufen, wenn n zu groß ist, wie dies in C (und Java) der Fall ist.

  • Wenn die Zahlen, die int darstellen kann, für die zu berechnenden Fakultäten zu klein sind, wählen Sie einen anderen Zahlentyp. long lang, wenn es nur ein bisschen größer sein muss, float oder double, wenn n nicht zu groß ist, und es Ihnen nichts ausmacht, wenn Sie die genauen Werte von wirklich großen Fakultäten wollen.

7
starblue

eine rekursive Version:

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

Hier ist ein C-Programm, das die BIGNUM-Implementierung von OPENSSL verwendet und daher für Studenten nicht besonders nützlich ist. (Natürlich ist die Annahme eines BIGNUM als Eingabeparameter verrückt, aber hilfreich, um die Interaktion zwischen BIGNUMs zu demonstrieren.).

#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;
}

Dieses Testprogramm zeigt, wie Sie eine Zahl für die Eingabe erstellen und was mit dem Rückgabewert zu tun ist:

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;
}

Mit gcc zusammengestellt:

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))

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

4
Anantha Kumaran

Dazu verwenden Sie den folgenden Code.

#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

Ich glaube nicht, dass ich dies in den meisten Fällen anwenden würde, aber eine bekannte Praxis, die immer weniger verbreitet wird, ist das Nachschlagen einer Tabelle. Wenn wir nur mit integrierten Typen arbeiten, ist der Speicherhit klein.

Nur ein anderer Ansatz, um das Poster auf eine andere Technik aufmerksam zu machen. Viele rekursive Lösungen können auch gespeichert werden, wodurch eine Nachschlagetabelle ausgefüllt wird, wenn der Algorithmus ausgeführt wird, wodurch die Kosten für zukünftige Aufrufe drastisch gesenkt werden (wie das Prinzip der .NET JIT-Kompilierung, denke ich).

3
Mr. Boy

Bei großen Zahlen können Sie wahrscheinlich mit einer ungefähren Lösung davonkommen, die tgamma Ihnen (n! = Gamma (n + 1)) von math.h gibt. Wenn Sie noch größere Zahlen wünschen, passen diese nicht in ein Doppel, daher sollten Sie stattdessen lgamma (natürliches Protokoll der Gamma-Funktion) verwenden.

Wenn Sie irgendwo ohne eine vollständige C99 math.h arbeiten, können Sie diese Art von Dingen problemlos selbst ausführen:

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

Einfache Lösung:

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

Am einfachsten und effizientesten ist es, Logarhitmen zusammenzufassen. Wenn Sie Log10 verwenden, erhalten Sie Leistung und Exponent.

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)

Möglicherweise müssen Sie den Code hinzufügen, damit der ganzzahlige Teil nicht zu sehr ansteigt und somit die Genauigkeit verringert. Das Ergebnis ist jedoch auch für sehr große Fakultäten in Ordnung.

2
Luka Rahne

Wir müssen von 1 bis zum angegebenen Limit sagen, sagen wir n. Beginnen Sie mit 1*2*3...*n.

In c schreibe ich es als Funktion.

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

Beispiel in C (C wurde mit Tags versehen, ich denke, das ist, was Sie wollen) mit Rekursion

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

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

Ich würde das mit einer vorberechneten Nachschlagetabelle machen, wie John sagte. Dies wäre schneller zu berechnen als eine iterative oder rekursive Lösung. Es hängt davon ab, wie schnell n! wächst, denn das größte n! Sie können berechnen, ohne einen unsigned long long zu überschreiten (maximaler Wert von 18.446.744.073.709.551.615). Dies ist nur 20!, sodass Sie nur ein Array mit 21 Elementen benötigen. So würde es in c aussehen:

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]; 
}

Überzeugen Sie sich selbst!

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