通用 排列组合 java类

本文介绍了一种简单的方法来生成组合和排列。通过定义两个类PbCb,实现了C(n,k)的所有组合和P(n,k)的所有排列。用户可以通过实现Cb_int和Pb_int接口来处理每次生成的组合或排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现了两个类Pb Cb,可以分别生成排列和组合。

Cb使用方法:
1. 在调用的地方,Cb cb=new Cb(n,k,this);cb.start();
这个地方表示生成c(n,k)的所有组合。
2. 在调用的类里面,实现Cb_int接口,作为每次一个组合的处理函数。
Cb_int的定义如下:
interface Cb_int{
public boolean callback(boolean[]a);
}
a[i]=true|false, 0<=i< n,其中,有k个数据是true,其余是false。
用户实现的回调函数如果返回true,那么cb_start()将会退出;如果是false,cb_start()将一直执行下去,直到所有的组合都处理完毕。

Pb使用方法:
1. 在调用的地方,Pb pb=new Pb(n,k,this);pb.start();
这个地方表示生成p(n,k)的所有排列。
2. 在调用的类里面,实现Pb_int接口,作为每次一个排列的处理函数。
Pb_int的定义如下:
interface Pb_int{
public boolean callback(int[]p);
}
其中,0<=p[i]<=n,0<=i< k。
用户实现的回调函数如果返回true,那么pb_start()将会退出;如果是false,pb_start()将一直执行下去,直到所有的排列都处理完毕。

代码和示例代码如下:

public class Cb{
    Cb_int mApi;
    private int mN;
    private int mK;
    public Cb(int n, int k, Cb_int api){
        this.mApi=api;
        this.setNK(n,k);
    }
    public interface Cb_int{
        public boolean callback(boolean[] a);
    }
    public void setNK(int n, int k){
        this.mK = k;
        this.mN = n;
    }
    boolean cb_real(int n, int k,int offset,boolean[]a, Cb_int api){
        if(0==k){
            for(int i=0;i<n;i++){
                a[i+offset]=false;
            }
            return api.callback(a);
        }else if(n==k){
            for(int i=0;i<n;i++){
                a[i+offset]=true;
            }
            return api.callback(a);
        }else{
            a[offset]=false;
            if(!cb_real(n-1,k,offset+1,a,api)){
                a[offset]=true;
                return cb_real(n-1,k-1,offset+1,a,api);
            }else{
                return true;
            }
        }
    }
    boolean cb(int n,int k, Cb_int api){
        if(n<0 || k<0 || k>n)
            return false;
        boolean[] all = new boolean[n];
        return cb_real(n,k,0,all,api);
    }
    boolean start(){
        return cb(mN,mK,mApi);
    }
}
public class Pb implements Cb.Cb_int{
    Pb_int mApi;
    private int mN;
    private int mK;
    private int[] mP;
    public interface Pb_int{
        public boolean callback(int[] p);
    }
    public Pb(int n, int k,Pb_int api){
        this.mApi=api;
        this.setNK(n,k);
    }
    public void setNK(int n, int k){
        this.mK = k;
        this.mN = n;
    }
    private boolean pb_real(int[] p,int offset, int num,Pb_int api){
        if(num==1 || num==0){
            return api.callback(p);
        }else{
            for(int  i=0;i<num;i++){
                int temp=p[0+offset];
                p[0+offset]=p[i+offset];
                p[i+offset]=temp;
                if(pb_real(p,offset+1,num-1,api))
                    return true;
                p[i+offset]=p[0+offset];
                p[0+offset]=temp;
            }
            return false;
        }
    }
    public boolean callback(boolean a[]){
        int index=0;
        for(int i=0;i<mN;i++){
            if(a[i])
                mP[index++]=i;
        }
        return pb_real(mP,0,mK, mApi);
    }
    private boolean pb(int n,int k){
        if(n<0 || k<0 || k>n){
            return false;
        }
        mP = new int[k];
        Cb cb = new Cb(mN,mK,this);
        return cb.start();
    }
    public boolean start(){
        return pb(mN,mK);
    }
}

demo

public class Test  implements Pb.Pb_int, Cb.Cb_int{
    private int mCounter=0;
    public boolean callback(boolean[] a){
        for(int i=0;i<a.length;i++){
            System.out.print(a[i]?"1 ":"0 ");
            //System.out.print();
        }
        System.out.println(new Integer(++mCounter).toString());
        return false;
    }
    public  boolean callback(int[]p){
        for(int i=0;i<p.length;i++){
            System.out.print(p[i]);
            System.out.print(" ");
        }
        System.out.println(new Integer(++mCounter).toString());
        return false;
    }
    public static void main(String args[]){
        Test test = new Test();  
        //组合demo
        //打印所有的c(5,3)
        Cb cb=new Cb(5,3,test);
        cb.start();
        //排列demo
        //打印所有的p(5,3)
        Pb spf=new Pb(5,3,test);
        this.mCounter=0;
        spf.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值