获取排列组合Cnm(n为下标,m为上标)的所有种类,以排序下标返回

 /**
     * 获取Cnm(n为下标,m为上标)的可组合的总种类数,由于long限制,n<21
     * @param n
     * @param m
     * @return
     */
    public static int cnm(int n,int m){
        if(n>20||n<1||n<m){
            throw new RuntimeException("n或m取值不当!");
        }
        long sum=1;
        for (int i = m+1; i <=n ; i++) {
            sum=sum*i;
        }
        for (int i = 1; i <n-m+1 ; i++) {
            sum=sum/i;
        }
        return  (int)sum;
    }

    /**
     * 获取排列组合Cnm(n为下标,m为上标)的所有种类,以排序下标返回
     * 由于long限制,n<21
     * @param n
     * @param m
     * @return
     */
    public static int[][] cnmArr(int n,int m){
        int num =cnm(n,m);
        int[][] arrS= new int[num][m];
        int[] arr= new int[m];
        for (int i = 0; i <arr.length ; i++) {
            arr[i]=i;
        }
        int i=0;
        while (true){
            System.arraycopy(arr,0,arrS[i],0,m);
            i++;
            if(!reSetArr(arr,n,m,m-1)){
                break;
            }
        }
        return arrS;
    }

    private static boolean reSetArr(int[] arr,int n,int m,int index){
        if(index<0){
            return false;
        }
        if(arr[index]<n-m+index){
            arr[index]++;
            for (int j = index; j <arr.length ; j++) {
                arr[j]=arr[index]+(j-index);
            }
            return true;
        }else {
            return reSetArr(arr,n,m,index-1);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值