好几个月没弄代码了,今天弄个求组合的DEMO
思路是将集合的每个值对照一个索引,索引大小是集合的大小+2.索引默认为[000...000],当组合后选取的组合值demo为[0100..00]。然后根据遍历索引来到集合中取值。
上代码:
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ComBit { public static void main(String[] args) { // Integer test int[] combination = new int[] { 1, 2, 3, 4 }; List<Integer> combinationlist = new ArrayList<Integer>(); for (Integer integer : combination) { combinationlist.add(integer); } ComBitIterator<Integer> i = new ComBitIterator<Integer>(combinationlist); while (i.hasNext()) { Object obj = i.next(); System.out.println(obj.toString()); } // String test String[] str = new String[] { "apple", "orange", "tomato", "potato" }; List<String> combinationSlist = new ArrayList<String>(); for (String s : str) { combinationSlist.add(s); } ComBitIterator<String> ii = new ComBitIterator<String>(combinationSlist); while (ii.hasNext()) { Object obj = ii.next(); System.out.println(obj.toString()); } } } class ComBitIterator<T> implements Iterator<T> { private int[] _bitArray = null; protected final int _length; protected final List<T> combination; protected List<T> _currentSet; public ComBitIterator(List<T> combination) { _currentSet = new ArrayList<T>(); this._length = combination.size(); this._bitArray = new int[_length + 2]; this.combination = combination; } @Override public boolean hasNext() { return _bitArray[_length + 1] != 1; } @SuppressWarnings("unchecked") @Override public T next() { _currentSet.clear(); for (int index = 1; index <= _length; index++) { if (_bitArray[index] == 1) { T value = combination.get(index - 1); _currentSet.add(value); } } int i = 1; while (_bitArray[i] == 1) { _bitArray[i] = 0; i++; } _bitArray[i] = 1; return (T) _currentSet; } }
------------------------------------------------分割线---------------------------------------------------------
PS:代码源于要求求数字1-20中 任取N的组合后合值为36,于是思路想到两种,第一种是递归,第二种虽然也是递归,但是想弄个通用的,就有了以上的代码。另外群里有人写出了直接递归的代码,也附上:
public static void main(String[] args) { combinateDataOfRange(1, 20, 36); } public static void combinateDataOfRange(int min, int max, int target) { combinateData(0, min, max, target, new Stack<Integer>()); } public static void combinateData(int sum, int min, int max, int target, Stack<Integer> stack) { for (int i = stack.isEmpty() ? min : (Integer) stack.lastElement() + 1; i < max; ++i) { int tempSum = sum + i; stack.push(i); if (tempSum == target) { System.out.println(stack + "=" + target); } else { combinateData(tempSum, min, max, target, stack); } stack.pop(); } }