【Java/算法/泛型】支持泛型的从数组中选择有限个数的组合器

 【代码】

package test230422;

import java.util.ArrayList;
import java.util.List;

/**
 * 从数组中选择有限个数的组合器,支持泛型
 * 比如从abc中选2个,会产生ab,ac,bc的结果
 */
public class Combiner2<T> {
    /**
     * 选择的结果
     */
    private List<List<T>> results;
    
    /**
     * 构造函数
     * @param candidates 候选者名单
     * @param selectCnt 选择的数量
     */
    public Combiner2(T[] candidates,int selectCnt) {
        int nCnt = candidates.length;
        
        if(selectCnt>nCnt) {
            throw new ArrayIndexOutOfBoundsException(selectCnt+">"+nCnt);
        }
        
        results=new ArrayList<>();

        int nBit = (0xFFFFFFFF >>> (32 - nCnt));

        for (int i = 1; i <= nBit; i++) {
            List<T> ls=new ArrayList<>();
            
            for (int j = 0; j < nCnt; j++) {
                if ((i << (31 - j)) >> 31 == -1) {
                    ls.add(candidates[j]);
                }
            }

            if(ls.size()==selectCnt) {
                results.add(ls);
            }
        }
    }
    
    /**
     * 取得选择的结果
     * @return
     */
    public List<List<T>> getResults(){
        return results;
    }
    
    /**
     * 使用示例
     * @param args
     */
    public static void main(String[] args) {
        // 1,2,3中选2
        Integer[] arr= {1,2,3};
        Combiner2<Integer> c1=new Combiner2<Integer>(arr,2);
        
        List<List<Integer>> results=c1.getResults();
        for(List<Integer> ls:results) {
            System.out.println(ls);
        }
        
        // "甲","乙","丙","丁"中选3
        String[] arr2= {"甲","乙","丙","丁"};
        Combiner2<String> c2=new Combiner2<String>(arr2,3);
        
        List<List<String>> results2=c2.getResults();
        for(List<String> ls:results2) {
            System.out.println(ls);
        }
    }
}

【输出】

[1, 2]
[1, 3]
[2, 3]
[甲, 乙, 丙]
[甲, 乙, 丁]
[甲, 丙, 丁]
[乙, 丙, 丁]

END

posted @ 2022-10-24 03:39  逆火狂飙  阅读(27)  评论(2编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东