JAVA组合函数Combination
来源:互联网 发布:oppoa59的手动网络在哪 编辑:程序博客网 时间:2024/05/22 02:22
JDK,Apache commons math里都没有发现组合函数,因而自己写了一个。
首先定义接口
package math.combination;import java.util.Collection;import java.util.List;/** * the interface for combination * @author jhren * * @param <T> */public interface Combinationable<T> {/** * get combinations from start to end [start, end] * it equals findCombiantions(start),findCombiantions(start+1), * ...... * findCombinations(end-1), findCombinations(end) */public List<List<T>> findCombinations(int start, int end);/** * get all combinations * it equals findCombinations(0, size) */public List<List<T>> findCombinations();/** * find a combinations for size * @param size * @return */public List<List<T>> findCombinations(int size);public Collection<T> getElements();}
第一个个实现,输出的组合会按照类型T升序排列
例如输入为[3,2,1]的全组合为
[]
[3]
[2]
[1]
[2, 3]
[1, 3]
[1, 2]
[1, 2, 3]
package math.combination;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import java.util.List;/** * the T should be Comparable the T in one combination list is sort by the * Comparable T * * @author jhren * * @param <T> */public class ComparableCombination<T extends Comparable<? super T>> implementsCombinationable<T> {private Collection<T> elements = new ArrayList<T>();public ComparableCombination(Collection<T> elements) {this.elements.addAll(elements);}@Overridepublic List<List<T>> findCombinations(int start, int end) {if (start < 0) {throw new IllegalArgumentException("start can't be negative: "+ start);}if (end > elements.size()) {throw new IllegalArgumentException("end can't be larger than elements size: " + end + ">"+ elements.size());}if(start > end) {throw new IllegalArgumentException("start can't be larger than end: " + start + ">"+ end);}List<List<T>> result = new ArrayList<List<T>>();for (int i = start; i <= end; i++) {result.addAll(findCombinations(i));}return result;}@Overridepublic List<List<T>> findCombinations() {return findCombinations(0, elements.size());}@Overridepublic List<List<T>> findCombinations(int size) {if (size < 0) {throw new IllegalArgumentException("size can't be negative: "+ size);}if (size > elements.size()) {throw new IllegalArgumentException("size can't be larger than elements size: " + size + ">"+ elements.size());}List<List<T>> result = new ArrayList<List<T>>();if (size == 0) {result.add(new ArrayList<T>());return result;}List<List<T>> combinations = findCombinations(size - 1);for (List<T> combination : combinations) {for (T element : elements) {if (combination.contains(element)) {continue;}List<T> list = new ArrayList<T>();list.addAll(combination);if (list.contains(element))continue;list.add(element);Collections.sort(list);if (result.contains(list))continue;result.add(list);}}return result;}@Overridepublic Collection<T> getElements() {return elements;}}
第二个实现,会保持元素的输入顺序
例如输入为[3,2,1]的全组合为
[]
[3]
[2]
[1]
[3, 2]
[3, 1]
[2, 1]
[3, 2, 1]
package math.combination;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.List;/** * the T in one combination list is sort by the input sequence * @author jhren * * @param <T> */public class CombinationSortByInput<T> implements Combinationable<T> {static private class Element<E> implements Comparable<Element<E>> {private int rank;private E e;public E getE() {return e;}private Element(E e, int rank) {this.e = e;this.rank = rank;}@Overridepublic int compareTo(Element<E> o) {return this.rank - o.rank;}}private Combinationable<Element<T>> combination = null;public CombinationSortByInput(Collection<T> elements) {Collection<Element<T>> elementsInput = convertCollection(elements);combination = new ComparableCombination<Element<T>>(elementsInput);}@Overridepublic List<List<T>> findCombinations(int start, int end) {List<List<Element<T>>> elementsOutput = combination.findCombinations(start, end);List<List<T>> output = convertListOfList(elementsOutput);return output;}@Overridepublic List<List<T>> findCombinations() {return findCombinations(0, combination.getElements().size());}@Overridepublic List<List<T>> findCombinations(int size) {return findCombinations(size,size);}private static <T> Collection<Element<T>> convertCollection(Collection<T> input) {Collection<Element<T>> elementCollectionInput = new ArrayList<Element<T>>();Iterator<T> iterator = input.iterator();int i = 0;while(iterator.hasNext()) {T t = iterator.next();Element<T> element = new Element<T>(t, i++);elementCollectionInput.add(element);}return elementCollectionInput;}private static <T> List<List<T>> convertListOfList(List<List<Element<T>>> elementsOutput) {List<List<T>> output = new ArrayList<List<T>>();for(List<Element<T>> elementList : elementsOutput) {List<T> tlist = convertList(elementList);output.add(tlist);}return output;}private static <T> List<T> convertList(Collection<Element<T>> elementList) {List<T> tlist = new ArrayList<T>();for(Element<T> element: elementList) {T t = element.getE();tlist.add(t);}return tlist;}@Overridepublic Collection<T> getElements() {return convertList(combination.getElements());}}
顺便附上TestNG unitestcode
package math.combination;import java.util.Arrays;import java.util.List;import math.combination.Combinationable;import math.combination.ComparableCombination;import org.testng.annotations.Test;import org.testng.annotations.BeforeClass;import static org.testng.AssertJUnit.assertNotNull;import static org.testng.AssertJUnit.assertEquals;import static org.testng.AssertJUnit.assertTrue;public class TestComparableCombination {private Combinationable<Integer> combination= null;@Testpublic void testGetElements() {assertNotNull(combination.getElements());assertEquals(3, combination.getElements().size());}@Testpublic void testFindCombinationsSizeZero() {List<List<Integer>> lists = combination.findCombinations(0);assertNotNull(lists);assertEquals(1, lists.size());assertNotNull(lists.get(0));assertEquals(0, lists.get(0).size());}@Test (expectedExceptions = IllegalArgumentException.class)public void testFindCombinationsSizeMinus() {combination.findCombinations(-1);}@Test (expectedExceptions = IllegalArgumentException.class)public void testFindCombinationsStartMinus() {combination.findCombinations(-1,2);}@Test (expectedExceptions = IllegalArgumentException.class)public void testFindCombinationsSizeOverflow() {combination.findCombinations(combination.getElements().size() + 1);}@Test (expectedExceptions = IllegalArgumentException.class)public void testFindCombinationsEndOverflow() {combination.findCombinations(0,combination.getElements().size() + 1);}@Test (expectedExceptions = IllegalArgumentException.class)public void testFindCombinationsStartEndWrongOrder() {combination.findCombinations(1,0);}@Testpublic void testFindCombinationsSizeTwo() {List<List<Integer>> lists = combination.findCombinations(2);assertNotNull(lists);assertEquals(3, lists.size());for(List<Integer> list: lists) {assertEquals(2, list.size());int element0 = list.get(0);int elements1 = list.get(1);assertTrue(element0 < elements1);}}@Testpublic void testFindAllCombinations1() {List<List<Integer>> lists = combination.findCombinations();assertNotNull(lists);assertEquals(8, lists.size());for(List<Integer> list : lists) {System.out.println(list);}}@Testpublic void testFindAllCombinations2() {List<List<Integer>> lists = combination.findCombinations(0, combination.getElements().size());assertNotNull(lists);assertEquals(8, lists.size());}@Test(timeOut=20000)public void testPerformance() {combination = new ComparableCombination<Integer>(Arrays.asList(3,2,1,4,5));for(int i = 0;i < 100000; i++) {combination.findCombinations();}}@BeforeClasspublic void beforeClass() {combination = new ComparableCombination<Integer>(Arrays.asList(3,2,1));}}
package math.combination;import java.util.Arrays;import java.util.List;import math.combination.CombinationSortByInput;import math.combination.Combinationable;import org.testng.annotations.Test;import org.testng.annotations.BeforeClass;import static org.testng.AssertJUnit.assertNotNull;import static org.testng.AssertJUnit.assertEquals;import static org.testng.AssertJUnit.assertTrue;public class TestCombinationSortByInput {private Combinationable<Integer> combination= null;@Testpublic void testGetElements() {assertNotNull(combination.getElements());assertEquals(3, combination.getElements().size());}@Testpublic void testFindCombinationsSizeZero() {List<List<Integer>> lists = combination.findCombinations(0);assertNotNull(lists);assertEquals(1, lists.size());assertNotNull(lists.get(0));assertEquals(0, lists.get(0).size());}@Test (expectedExceptions = IllegalArgumentException.class)public void testFindCombinationsSizeMinus() {combination.findCombinations(-1);}@Test (expectedExceptions = IllegalArgumentException.class)public void testFindCombinationsSizeOverflow() {combination.findCombinations(combination.getElements().size() + 1);}@Testpublic void testFindCombinationsSizeTwo() {List<List<Integer>> lists = combination.findCombinations(2);assertNotNull(lists);assertEquals(3, lists.size());for(List<Integer> list: lists) {assertEquals(2, list.size());int element0 = list.get(0);int elements1 = list.get(1);assertTrue(element0 > elements1);}}@Testpublic void testFindAllCombinations1() {List<List<Integer>> lists = combination.findCombinations();assertNotNull(lists);assertEquals(8, lists.size());for(List<Integer> list : lists) {System.out.println(list);}}@Testpublic void testFindAllCombinations2() {List<List<Integer>> lists = combination.findCombinations(0, combination.getElements().size());assertNotNull(lists);assertEquals(8, lists.size());}@BeforeClasspublic void beforeClass() {combination = new CombinationSortByInput<Integer>(Arrays.asList(3,2,1));}@Test(timeOut=20000)public void testPerformance() {combination = new CombinationSortByInput<Integer>(Arrays.asList(3,2,1,4,5));for(int i = 0;i < 100000; i++) {combination.findCombinations();}}}
- JAVA组合函数Combination
- 组合(Combination)
- [Java代码] [Leetcode] Combination Sum 组合数之和
- [Java代码] [Leetcode] Combination Sum 组合数之和
- leetcode解题之 Combination Sum java 版(组合求和)
- 组合算法 combination 源代码
- 组合生成 Combination Sum
- [leetcode]Combination组合
- 关于组合-combination sum
- Food combination ZJU2861 组合数学
- Combination Sum 组合数之和
- 凸组合(convex combination)
- UVALive 6844 Combination(组合数学)
- Combination Sum IV 组合数
- js创建对象的构造函数模式+原型模式和组合继承\Hybrid Pattern & combination inheritance
- 【LeetCode-面试算法经典-Java实现】【216-Combination Sum III (组合数的和)】
- leetcode解题之 Combination Sum III java 版(组合求和III)
- Leetcode 216 Combination Sum III 组合求和
- javascript优化策略 技巧一
- C# DataSet类
- 第三方支付原理与概述
- 在Chrome浏览器中保存的密码有多安全?
- 性能测试原理及性能测试实例分析
- JAVA组合函数Combination
- 国内各种在线支付方式汇总
- Android游戏开发十日通(1)-游戏编程基础
- 我是这样在Google paly上赚美刀的
- C++拷贝构造函数(深拷贝,浅拷贝)
- JAVA摄像头调用_实例---Win7
- spring mvc Hello World 的例子
- java判断字符串相等
- [iOS] getter and setter, @property and @synthesize