我试图计算可能组合的数量,所以我在这里使用一些数学(精确的阶乘)。例如,如果我有50个数字并且我想将它们组织成5个组,那么可以制作多少组(组合)。我使用这个公式:while true:
x = input("Enter your data in the form of [text] [number]: ")
if len(x.split()) > 1 and x.split()[0].isdigit():
break
,但是这个特定的例子会出现错误。它说禁止除以零。如何管理这项工作?
这是我的代码:
allNumbers! / (allNumbers - PerGroup)!
答案 0 :(得分:2)
Enumerable.Range(1,int.MaxValue).Contains(b/n)
检查不检查该值是否有效,因为b / n已经计算并且此时存储为int。
由于变量n溢出并变为零,因此除以零。在下面的代码中,您可以看到溢出是如何发生的。
using System;
public class Test
{
public static void Main()
{
int n = 1;
for (int i = 1; i <= 50; i++) {
n *= i;
Console.WriteLine("i = {0}, n = {1}", i, n);
}
}
}
输出:
i = 1, n = 1
i = 2, n = 2
i = 3, n = 6
i = 4, n = 24
i = 5, n = 120
i = 6, n = 720
i = 7, n = 5040
i = 8, n = 40320
i = 9, n = 362880
i = 10, n = 3628800
i = 11, n = 39916800
i = 12, n = 479001600
i = 13, n = 1932053504
i = 14, n = 1278945280
i = 15, n = 2004310016
i = 16, n = 2004189184
i = 17, n = -288522240
i = 18, n = -898433024
i = 19, n = 109641728
i = 20, n = -2102132736
i = 21, n = -1195114496
i = 22, n = -522715136
i = 23, n = 862453760
i = 24, n = -775946240
i = 25, n = 2076180480
i = 26, n = -1853882368
i = 27, n = 1484783616
i = 28, n = -1375731712
i = 29, n = -1241513984
i = 30, n = 1409286144
i = 31, n = 738197504
i = 32, n = -2147483648
i = 33, n = -2147483648
i = 34, n = 0
i = 35, n = 0
i = 36, n = 0
i = 37, n = 0
i = 38, n = 0
i = 39, n = 0
i = 40, n = 0
i = 41, n = 0
i = 42, n = 0
i = 43, n = 0
i = 44, n = 0
i = 45, n = 0
i = 46, n = 0
i = 47, n = 0
i = 48, n = 0
i = 49, n = 0
i = 50, n = 0
答案 1 :(得分:1)
由于allNumbers!
始终包含(allNumbers - PerGroup)!
,为什么不将它们从开头排除。
int b = 1;
if (allNumbers - PerGroup == 0)
{
return 1;
}
else if (allNumbers - PerGroup == 1)
{
return allNumbers;
}
else
{
for (int i = (allNumbers - PerGroup + 1); i <= allNumbers; i++)
{
b *= i;
}
return b;
}
答案 2 :(得分:0)
我猜错误是OutOfMemoryException,因为你创建了大量不必要的 integers
。 (Enumerable.Range(1,int.MaxValue)
)请注意每个int
从您的记忆中获取4
个字节。
我不确定你在那里尝试做什么,但你可以使用double
类型,所以如果数字变得非常大,它只会给你PositiveInfinity
。
或者您可以使用checked
通过try和catch控制整数溢出。
另一种方法是在整数溢出发生时预先计算数字。例如,int
的阶乘14将溢出,而long
的阶乘22将溢出。
此外,您不必为循环写两次。你可以用这个方法。
您无需检查allNumbers - PerGroup == 0
以防止零分割。这不会发生,因为0的阶乘是1,当输入为0时,我们的阶乘实现按性质返回1! (因为for循环在这种情况下从不迭代,计数器从1开始。)
private static int Cominations(int allNumbers, int perGroup)
{
if(allNumbers > 13)
{
Console.WriteLine("Too big number!");
return -1;
}
return Factorial(allNumbers)/Factorial(allNumbers - perGroup);
}
private static int Factorial(int number)
{
int n = 1;
for (int i = 1; i < number; i++)
{
n *= i;
}
return n; // returns 1 when number is 0
}
如果要计算较大数字的阶乘,请使用System.Numberics命名空间中的BigInteger
类型。
using System.Numerics;
//...
private static BigInteger Factorial(int number)
{
BigInteger n = 1;
for (int i = 1; i < number; i++)
{
n *= i;
}
return n;
}