我有一个计算阶乘和组合的函数如下。
int faktorial(int n)
{
if( (n == 0)||(n == 1))
{
return (1);
}
else
{
return (n * faktorial(n-1));
}
}
int Kombinasi(int x, int y)
{
int n = faktorial(x);
int k = (faktorial(x - y)) * (faktorial(y));
int hasil = n / k;
return (hasil);
}
但是在计算阶乘时存在问题。 假设我想计算x = 1000和y = 4的组合。现有的呼叫因子函数组合的功能。但是阶乘函数无法计算它们。如何解决这个问题呢 ?。抱歉,我的英语很不好。感谢。
答案 0 :(得分:2)
BigInteger
可以正常工作,并且速度很快!。
BigInteger faktorial(BigInteger n)
{
if ((n == 0) || (n == 1))
{
return (1);
}
else
{
return (n * faktorial(n - 1));
}
}
BigInteger Kombinasi(BigInteger x, BigInteger y)
{
BigInteger n = faktorial(x);
BigInteger k = (faktorial(x - y)) * (faktorial(y));
BigInteger hasil = n / k;
return (hasil);
}
答案:
4023872600770937735437024339230039857193748642107146325437999104299385123986290205920442084869694048004799886101971960586316668729948085589013238296699445909974245040870737599188236277271887325197795059509952761208749754624970436014182780946464962910563938874378864873371191810458257836478499770124766328898359557354325131853239584630755574091142624174743493475534286465766116677973966688202912073791438537195882498081268678383745597317461360853795345242215865932019280908782973084313928444032812315586110369768013573042161687476096758713483120254785893207671691324484262361314125087802080002616831510273418279777047846358681701643650241536913982812648102130927612448963599287051149649754199093422215668325720808213331861168115536158365469840467089756029009505376164758477284218896796462449451607653534081989013854424879849599533191017233555566021394503997362807501378376153071277619268490343526252000158885351473316117021039681759215109077880193931781141945452572238655414610628921879602238389714 7608850627686296714667469756291123408243920816015378088989396451826324367161676217916890977991190375403127462228998800519544441428201218736174599264295658174662830295557029902432415318161721046583203678690611726015878352075151628422554026517048330422614397428693306169089796848259012545832716822645806652676995865268227280707578139185817888965220816434834482599326604336766017699961283186078838615027946595513115655203609398818061213855860030143569452722420634463179746059468257310379008402443243846565724501440282188525247093519062092902313649327349756551395872055965422874977401141334696271542284586237738753823048386568897646192738381490014076731044664025989949022222176590433990188601856652648506179970235619389701786004081188972991831102117122984590164192106888438712185564612496079872290851929681937238864261483965738229112312502418664935314397013742853192664987533721894069428143411852015801412334482801505139969429015348307764456909907315243327828826986460278986432113908350621709500259738986 3554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
注意,但它似乎在8889左右溢出堆栈!。
答案 1 :(得分:1)
首先,要回答您的问题 - 如果您使用
,您可以处理更大的值(最多2 ^ 64 - 1)ulong c;
第二,一点帮助 - 这对你的锻炼没有帮助。即使是unsigned long也无法处理如此大的值。但是,请注意,要获得(n选择k),您可以简单地计算(n *(n - 1)* .... *(n - k + 1))/ k !,它处理更小的值
答案 2 :(得分:1)
由于看起来你真正想做的是计算二项式系数,使用BigInteger
的另一种方法是利用因子的一些数值属性。因此,不是直接计算阶乘(可能很大),而是可以这样做:
long Kombinasi(long x, long y)
{
if( y == 0 ) return 1;
return ( x * Kombinasi( x - 1, y - 1 ) ) / y;
}
如果您需要更大的值,也可以将此算法与BigInteger
结合使用:
BigInteger Binomial( BigInteger n, BigInteger k )
{
if( k <= 0 ) return 1;
return ( n * Binomial( n - 1, k - 1 ) ) / k;
}
这比计算阶乘和除法更有效,因为它利用了大多数阶乘项抵消的事实。它也会执行较少的乘法运算,尤其是k
很小的情况。
答案 3 :(得分:0)
正如其他成员所建议的,我们可以使用BitInteger
来表示大数字。
我不知道它是否有用,但我想在这里解释一点。
所以我们假设我们有一个带有大值(int.Max
)的signed int,如果你试图添加一些正整数值(10),它就不会给你System.OverflowException
。它只是给你负值。所以如果你想在这种情况下引发异常。您可以使用checked
关键字。如果表达式生成的值超出目标类型的范围。如果表达式包含一个或多个非常量值,则编译器不会检测溢出。可以使用checked关键字启用溢出检查。因此,当您尝试上面提到的内容时,它会抛出异常,您可以相应地处理它。