再谈排列数和组合数
本版原来精华帖中给的算法,窃以为都不够好。它们能够很快的打出100的阶乘(或组合数)的第10000000个排列是什么吗?
下面的算法给出这个答案。相信只要高中毕业,认真想想就可以明白了。我以前用Fortran77写过一个,刚学C++不想去调试。先只给算法吧。
使用一个辅助数组存储(1!,2!,3!,...,n!)然后根据阶乘数的特性(i开头的排列数共有(n-1)!种)。可以方便的输出任意位置的排列数。
组合数的话使用杨辉三角,也可以实现输出任意位置的组合数。
另外递归算法内存消耗很大,对大数无能为力。排列数和组合数的生成可以使用n进制来实现。
4个数中任意挑3个的排列数情形:
123,124,132,134,142,143,213,214,231,234,241,243,312,314,321,324,341,342.
第一个顺序写出1到n。下一个最后一位加1。加到没法加时,会到前一为数加一。其后的数从最小的开始再排。然后又是最后一位开始加,一直进行下去直到第一位无法加为止。(注:可以证明阶乘数的全体集合等于n位的n进制数中去掉有相同数字的那些数。)
组合数的情况类似。只是要求后面的数大于前面的数。更好处理一些。
如何找出100!的第10000000个排列数是什么?
k1=10000000/99!; // 第一位为k1+1
l1=10000000%99!;
k2=l/98!;//第二位为1,2,...,k1,k1+2,...,100中的第k2+1个数
...
...
这样可以直接找出100!的第10000000个排列数是什么。
欢迎讨论,还有更好的算法吗?