从五个数任意选3个数为一个组合,最多能有几个组合哦

Image

从五个不重复的数(0-9) 选取3个为一个组合 顺序了不同 最多能有多少组合?
js来写 如果可以的话 能不用es6就不用(还不会)
ps: 我来做的话也就想到三重循环那种笨方法
要是能有简洁的写法就好了
在扩展一下如果也适合6个数选取4个数为一组合的就好了...
你们不要在数学算了(数学差也不会算) 我发这个问题是想用js输出这些可以组合的数字 而不是再求数学题
阅读 32k
3 个回答

第1个可能,只有5个不重复的数,5个数中取3个组合,是C(5,3)=P(5,3)/(3!)=C(5,2)=P(5,2)/(2!)=5!/((5-2)!)/2!=10

第2个可能,其实是有10个不重复的数,分成两步,先选5个不重复的数,再在这5个数中选3个来组合,最后的组合有多少种,其实这个问题就是在10个不同数中选3个来组合,即C(10,3)=P(10,3)/(3!)=10!/((10-3)!)/3!= 10!/(7! * 3!) = 120


上面是以往的回答,下面是对其实质问题的回答


的javascript实现

// 对N个元素取M组合的序数排列可能全输出函数
// 其返回一个二维数组,数组长度是可能的数量,每个子数组有M个元素,每个元素值代表其取原始数组的序号。
function mcom(n,m){
                var rt=[];
                for (var i=0;i<Math.pow(2,n);i++){
                    var a=0;
                    var tmp=[];
                    for (var j=0;j<n;j++){
                        if(i>>j & 1){
                            a++;
                            tmp.push(j);
                        }
                    }
                    if(a==m){
                        rt.push(tmp);
                    }
                }
                return rt;
            }

上面的代码利用了位运算,其原理其实很简单,它产生一个N个元素的所有可能组合(对应于0至 111...111 的二进制数,其中后面一个有N个1),然后过滤出恰好有M个1的数,就是所要求的,所以这个效率其实不高的,特别是对于N很大时。


鉴于题主不理解上面实现的原理,我再详细解释一下。
对于N个不重复元素,其取得0个到N个元素组合的可能C(N,M) (0<=M<=N)如果用二进制表示,就是,用A(N)表示所有N位二进制数,包括N个0的,即范围为[0,Power(2,N)-1]的非负整数集合,可以知道对于任何组合可能其实对应于一个A(N)内的整数,记这个数C(N,M) 其还满足以下对应条件:
M=0 --- C(N,0) 所有位均为0,即没有为1的位
M=1 --- C(N,1) 有且仅有1位为1
M=2 --- C(N,2) 有且仅有2位位1
...
M=N ---C(N,N) 所有位都位1


以 楼主 开始要求的在[1,2,3,4,5]中取3个都组合 举例就是:

    元素                
1   2   3   4   5
 对应的二进制数        对应十进制数    取得的组合
1   1   1   0   0      28            1,2,3
1   1   0   1   0      26            1,2,4      
1   1   0   0   1      25            1,2,5
1   0   1   1   0      22            1,3,4
1   0   1   0   1      21            1,3,5
1   0   0   1   1      19            1,4,5
0   1   1   1   0      14            2,3,4
0   1   1   0   1      13            2,3,5
0   1   0   1   1      11            2,4,5
0   0   1   1   1      7             3,4,5

可见,只要通过位运算来过滤出[0,Power(2,N)-1]的非负整数集合中满足只有M位为1的数就可以找到对应的组合。这就是前面算法的实现原理。

其中过滤操作是通过位运算 X&1实现,具体过滤对应于:

                    for (var j=0;j<n;j++){
                        if(i>>j & 1){
                            a++;
                            tmp.push(j);
                        }
                    }
                    if(a==m){
                        rt.push(tmp);
                    }

,还是继续上面的例子,以4,7、15分别为例,这里n=5了,m=3,

4的二进制为100,这时i=4所以有
j=0, 4>>0=4  4 & 1 =0 
j=1, 4>>1=2  2 & 1 =0
j=2, 4>>2=1  1 & 1 =1,  a=1, tmp=[2]
直到循环结束 a=1,tmp=[2],  因为a<m,所以rt不增加tmp这个可能

7的二进制为111,这时i=7所以有
j=0, 7>>0=7  7 & 1 =1,  a=1, tmp=[0] 
j=1, 7>>1=3  3 & 1 =1,  a=2, tmp=[0,1]
j=2, 7>>2=1  1 & 1 =1,  a=3, tmp=[0,1,2]
直到循环结束 a=3,tmp=[0,1,2],  因为a=m,所以rt增加tmp这个可能

15的二进制为1111,这时i=15所以有
j=0, 15>>0=15  15 & 1 =1,  a=1, tmp=[0] 
j=1, 15>>1=7   7 & 1 =1,  a=2, tmp=[0,1]
j=2, 15>>2=3   3 & 1 =1,  a=3, tmp=[0,1,2]
j=3, 15>>3=1   1 & 1 =1,  a=4, tmp=[0,1,2,3]
直到循环结束 a=4,tmp=[0,1,2,3],  因为a>m,所以rt不增加tmp这个可能

1.你这是数学问题,不是程序问题
2.你说顺序不限,那就是可以重复,任意5个数里选三个数,那就是5x5x5=125种组合
3.推而广之,n个数里选m个数,那就是n的m次方Math.pow(n,m)

推荐问题