JAVA流式组合数算法--集合取子集

package com.kejin.lafite.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class SubSet<T> implements Iterable<List<T>>, Iterator<List<T>> {

	private List<T> data;
	private int[] p;
	private int dataSize;
	private int subSize;
	private int lessSize;
	
	public long size(){  
        int m=subSize;
        int n=dataSize;
        if (n == 0 || m == 0){  
            return 1;  
        }  
        if (m > n){  
            return 0;  
        }  
        if (m > n/2.0){  
            m = n-m;  
        }  
        double result = 0.0;  
        for (int i=n; i>=(n-m+1); i--){  
            result += Math.log(i);  
        }  
        for (int i=m; i>=1; i--){  
            result -= Math.log(i);  
        } 
        
        result = Math.exp(result);  
        return Math.round(result);  
    }  

	public SubSet(int i, List<T> data) {
		if (i > data.size()) {
			throw new IllegalArgumentException("选取数量不能超过集合大小");
		}
		this.data = data;
		this.p = new int[i];
		dataSize = data.size();
		subSize = i;
		lessSize = dataSize - subSize;
		for (int s = 0; s < i; s++) {
			p[s] = s;
		}
	}

	public SubSet(int i, Collection<T> data) {
		if (i > data.size()) {
			throw new IllegalArgumentException("选取数量不能超过集合大小");
		}
		this.data = new ArrayList<T>();
		this.p = new int[i];
		for (int s = 0; s < i; s++) {
			p[s] = s;
		}
		this.data.addAll(data);
		dataSize = data.size();
		subSize = i;
		lessSize = dataSize - subSize;
	}

	private int isend = 0;

	public List<T> readOne() {
		if (isend == -1) {
			return null;
		}
		List<T> one = new ArrayList<T>();
		for (int s : p) {
			one.add(data.get(s));
		}
		isend = move(subSize - 1);
		return one;
	}

	private int move(int i) {
		if (p[i] == (lessSize + i)) {
			if (i != 0) {
				int head = move(i - 1);
				if (head == -1)
					return head;
				p[i] = head + 1;
				return p[i];
			} else {
				return -1;
			}
		} else {
			p[i]++;
			return p[i];
		}
	}

	@Override
	public boolean hasNext() {

		return isend != -1;
	}

	@Override
	public List<T> next() {
		return readOne();
	}

	@Override
	public void remove() {

	}

	@Override
	public Iterator<List<T>> iterator() {
		return this;
	}
	
	public static void main(String[] args) {
		List<Integer> s=new ArrayList<Integer>();
		for (int i = 0; i < 20; i++) {
			s.add(i);
		}
		SubSet<Integer> sub=new SubSet<Integer>(6, s);
		int i=0;
		System.out.println(sub.size());
		for (List<Integer> list : sub) {
			i++;
		}
		System.out.println(i);
		
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值