Coverage Report - org.eclipse.swtbot.swt.finder.CombinationGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
CombinationGenerator
100%
12/12
100%
4/4
2.077
CombinationGenerator$FixedSizeCombinationGenerator
89%
41/46
88%
16/18
2.077
 
 1  511
 /*******************************************************************************
 2  
  * Copyright (c) 2008 Ketan Padegaonkar and others.
 3  
  * All rights reserved. This program and the accompanying materials
 4  
  * are made available under the terms of the Eclipse Public License v1.0
 5  
  * which accompanies this distribution, and is available at
 6  
  * http://www.eclipse.org/legal/epl-v10.html
 7  
  *
 8  
  * Contributors:
 9  
  *     Ketan Padegaonkar - initial API and implementation
 10  
  *******************************************************************************/
 11  
 package org.eclipse.swtbot.swt.finder;
 12  
 
 13  
 import java.math.BigInteger;
 14  
 import java.util.ArrayList;
 15  
 import java.util.Iterator;
 16  
 import java.util.List;
 17  
 
 18  
 /**
 19  
  * Generates a combination of the specified elements.
 20  
  *
 21  
  * @author Ketan Padegaonkar <KetanPadegaonkar [at] gmail [dot] com>
 22  
  * @version $Id$
 23  
  */
 24  
 class CombinationGenerator<T> implements Iterable<List<T>> {
 25  
 
 26  
         private final int                        r;
 27  
         private final T[]                        values;
 28  
         private ArrayList<List<T>>        result;
 29  
 
 30  
         /**
 31  
          * @param r the number of elements in the combination
 32  
          * @param values the values that should be combined.
 33  
          */
 34  1
         CombinationGenerator(int r, T... values) {
 35  1
                 this.r = r;
 36  1
                 this.values = values;
 37  1
                 initialize();
 38  1
         }
 39  
 
 40  
         private void initialize() {
 41  1
                 result = new ArrayList<List<T>>();
 42  10
                 for (int i = 1; i <= r; i++) {
 43  9
                         FixedSizeCombinationGenerator<T> combinationGenerator = new FixedSizeCombinationGenerator<T>(i, values);
 44  529
                         for (List<T> list : combinationGenerator) {
 45  511
                                 result.add(list);
 46  
                         }
 47  
                 }
 48  1
         }
 49  
 
 50  
         public Iterator<List<T>> iterator() {
 51  1
                 return result.iterator();
 52  
         }
 53  
 
 54  
         class FixedSizeCombinationGenerator<E> implements Iterator<List<E>>, Iterable<List<E>> {
 55  
                 private int[]                a;
 56  
                 private int                        n;
 57  
                 private int                        r;
 58  
                 private BigInteger        numLeft;
 59  
                 private BigInteger        total;
 60  
                 private final E[]        elements;
 61  
 
 62  9
                 FixedSizeCombinationGenerator(int r, E... elements) {
 63  9
                         this.elements = elements;
 64  9
                         int n = elements.length;
 65  9
                         if (r > n) {
 66  0
                                 throw new IllegalArgumentException();
 67  
                         }
 68  9
                         if (n < 1) {
 69  0
                                 throw new IllegalArgumentException();
 70  
                         }
 71  9
                         this.n = n;
 72  9
                         this.r = r;
 73  9
                         a = new int[r];
 74  9
                         BigInteger nFact = getFactorial(n);
 75  9
                         BigInteger rFact = getFactorial(r);
 76  9
                         BigInteger nminusrFact = getFactorial(n - r);
 77  9
                         total = nFact.divide(rFact.multiply(nminusrFact));
 78  9
                         reset();
 79  9
                 }
 80  
 
 81  
                 public void reset() {
 82  54
                         for (int i = 0; i < a.length; i++) {
 83  45
                                 a[i] = i;
 84  
                         }
 85  9
                         numLeft = new BigInteger(total.toString());
 86  9
                 }
 87  
 
 88  
                 public BigInteger getNumLeft() {
 89  0
                         return numLeft;
 90  
                 }
 91  
 
 92  
                 public BigInteger getTotal() {
 93  0
                         return total;
 94  
                 }
 95  
 
 96  
                 private BigInteger getFactorial(int n) {
 97  27
                         BigInteger fact = BigInteger.ONE;
 98  163
                         for (int i = n; i > 1; i--) {
 99  136
                                 fact = fact.multiply(new BigInteger(Integer.toString(i)));
 100  
                         }
 101  27
                         return fact;
 102  
                 }
 103  
 
 104  
                 private int[] getIndices() {
 105  511
                         if (numLeft.equals(total)) {
 106  9
                                 numLeft = numLeft.subtract(BigInteger.ONE);
 107  9
                                 return a;
 108  
                         }
 109  
 
 110  502
                         int i = r - 1;
 111  1470
                         while (a[i] == n - r + i) {
 112  466
                                 i--;
 113  
                         }
 114  502
                         a[i] = a[i] + 1;
 115  968
                         for (int j = i + 1; j < r; j++) {
 116  466
                                 a[j] = a[i] + j - i;
 117  
                         }
 118  502
                         numLeft = numLeft.subtract(BigInteger.ONE);
 119  502
                         return a;
 120  
                 }
 121  
 
 122  
                 public boolean hasNext() {
 123  520
                         return numLeft.compareTo(BigInteger.ZERO) == 1;
 124  
                 }
 125  
 
 126  
                 public List<E> next() {
 127  511
                         ArrayList<E> arrayList = new ArrayList<E>();
 128  511
                         int[] indices = getIndices();
 129  2815
                         for (int i = 0; i < indices.length; i++) {
 130  2304
                                 arrayList.add(elements[indices[i]]);
 131  
                         }
 132  511
                         return arrayList;
 133  
                 }
 134  
 
 135  
                 public void remove() {
 136  0
                         throw new UnsupportedOperationException();
 137  
                 }
 138  
 
 139  
                 public Iterator<List<E>> iterator() {
 140  9
                         return this;
 141  
                 }
 142  
         }
 143  
 
 144  
 }