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);
}
}
JAVA流式组合数算法--集合取子集
最新推荐文章于 2024-07-04 14:43:05 发布