有一组元素,在本例中是一个包含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中链接公式及其实现,将非常感激。
答案 0 :(得分:2)
让我们尝试使用三个字符A
,B
和C
(n = 3
)和组合长度k = 2
,如您的示例所示。< / p>
这为您提供了3 × 3
种可能性。
一般来说,有n ^ k
种可能性。
这为您提供3 × 2
种可能性。
让我们再举一个例子。比如说,你有五个字母(ABCDE
)和四个_ _ _ _
的组合长度。
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 = 5
和k = 4
示例对此进行测试。我们说公式是5 × 4 × 3 × 2
。现在看一下通用公式:实际上,我们从n = 5
开始并继续乘以我们达到5 - 4 + 1 = 2
的数字。
在您的函数签名中,n
为setLength
,k
为comboLength
。使用上述公式实现应该是微不足道的,所以我将其留给读者。
这些被称为permutations,有或没有重复。