计算具有指定组合长度的集合的总量(数量)?

时间:2017-09-03 13:34:03

标签: c# .net vb.net math combinations

有一组元素,在本例中是一个包含3个字符/元素{A,B,C}的数组:

char[] charSet = "ABC".ToCharArray();

我想写一个通用的使用函数,以帮助确定哪个是指定长度可以生成的组合的总量,并确定有或没有重复的可能组合的数量。为了避免可能的错误:这个问题不是关于组合/烫发生成,只是计算。

一个简单的未完成的例子来理解我:

public static long CalculateCombinations(int setLength, int comboLength, bool allowRepetition)
{
    return result;
}

(其中setLength是集合中元素的数量,comboLength是每个组合的所需长度,allowRepetition是一个确定性标志,用于帮助计算组合时的数量和当每个组合中不允许重复元素时。)

然后,如果我有上面指定的相同字符集,并且我想计算重复的可能组合的数量,算法应该返回值9,这将是这个组合的等价量: / p>

1: AA
2: AB
3: AC
4: BA
5: BB
6: BC
7: CA
8: CB
9: CC

如果我不想重复,同样的算法应该给我一个值6,这相当于这组合的数量:

1: AB
2: AC
3: BA
4: BC
5: CA
6: CB

基本上我正在尝试重现这个在线服务可以做什么:http://textmechanic.com/text-tools/combination-permutation-tools/combination-generator/但是我试图在WWW周围调查和实现不同的'nCr'公式(如http://www.vcskicks.com/code-snippet/combination.php)和 StackOverflow 线程(如https://stackoverflow.com/a/26312275/1248295),但是当计算中涉及组合长度因子和重复时,我不知道如何计算它。也许这可能比我看起来的那么基本,但数学不是我的强项。

我的问题:如何编写可以计算我解释的算法?如果有人可以在C#或VB.NET中链接公式及其实现,将非常感激。

1 个答案:

答案 0 :(得分:2)

让我们尝试使用三个字符ABCn = 3)和组合长度k = 2,如您的示例所示。< / p>

重复

  • 我们从两个空格开始。
  • 可以用3种可能的方式填充第一个空白区域。
  • 对于三种可能的方式中的每一种,第二种空间可以用另外三种可能的方式填充。

这为您提供了3 × 3种可能性。

一般来说,有n ^ k种可能性。

不重复

  • 我们从两个空格开始。
  • 可以用3种可能的方式填充第一个空白区域。
  • 第二个空白区域可以通过两种可能的方式填充,因为您不想重复自己。

这为您提供3 × 2种可能性。

让我们再举一个例子。比如说,你有五个字母(ABCDE)和四个_ _ _ _的组合长度。

  • 我们在第一个空白区域放了五个字母。这有五种可能性:A,B,C,D,E。
  • 现在,对于最后一步之后的每种可能性,无论我们选择哪一封信,现在我们还有4个字母可供选择。如果在上一步中我们选择A,则语料库现在为BCDE - 这是四种可能性。对于B,我们选择ACDE - 这也是可能性。总的来说,由于有5种方法可以执行上一步,并且有4种方法可以在之前的任何之后进行,所以总共20可能性:(AB,AC,AD,AE),(BA,BC,BD,BE),(CA,CB,CD,CE),(DA,DB,DC,DE),(EA,EB,EC, ED)。
  • 让我们继续吧。选中两个字母后,我们留下了3。使用与以前相同的逻辑,对于前20种可能性中的每一种,我们有另外3种可能性。总共60
  • 还剩下一个空间。我们有两封信,我们以前没有选过。从以前60的任何可能性来看,我们现在有两种可能性。总共120

所以我们通过乘以5 × 4 × 3 × 2来实现这个目标。为什么从5开始?因为我们最初有5个字母:ABCDE。为什么我们的乘法中有四个数字?因为有4个空格:_ _ _ _

一般情况下,您将继续乘以从n开始的递减值,并执行此k次:n × (n - 1) × ... × (n - k + 1)

最后一个值为(n - k + 1),因为您总共乘以k个值。从n(n - k + 1)总共有k个值(含)。

我们可以使用n = 5k = 4示例对此进行测试。我们说公式是5 × 4 × 3 × 2。现在看一下通用公式:实际上,我们从n = 5开始并继续乘以我们达到5 - 4 + 1 = 2的数字。

在您的函数签名中,nsetLengthkcomboLength。使用上述公式实现应该是微不足道的,所以我将其留给读者。

这些被称为permutations,有或没有重复。