View Javadoc
1   package net.bmahe.genetics4j.core.util;
2   
3   import java.util.Arrays;
4   
5   import org.apache.commons.lang3.Validate;
6   
7   public class MultiIntCounter {
8   
9   	final int[] indices;
10  	final int[] maxIndices;
11  
12  	public MultiIntCounter(final int... maxIndices) {
13  		Validate.notNull(maxIndices);
14  		Validate.isTrue(maxIndices.length > 0);
15  
16  		for (int i = 0; i < maxIndices.length; i++) {
17  			final int maxIndex = maxIndices[i];
18  			Validate.isTrue(maxIndex > 0);
19  		}
20  
21  		this.indices = new int[maxIndices.length];
22  		this.maxIndices = Arrays.copyOf(maxIndices, maxIndices.length);
23  	}
24  
25  	public int[] getIndices() {
26  		return indices;
27  	}
28  
29  	public int getIndex(final int index) {
30  		Validate.isTrue(index >= 0);
31  		Validate.isTrue(index < indices.length);
32  
33  		return indices[index];
34  	}
35  
36  	public int[] getMaxIndices() {
37  		return maxIndices;
38  	}
39  
40  	public int getTotal() {
41  		int total = 1;
42  		for (int i : maxIndices) {
43  			total *= i;
44  		}
45  		return total;
46  	}
47  
48  	public boolean hasNext() {
49  
50  		/**
51  		 * Precondition check if we tried all the combinations
52  		 */
53  		boolean allToTheMax = false;
54  		for (int i = 0; i < indices.length && !allToTheMax; i++) {
55  			if (indices[i] >= maxIndices[i]) {
56  				allToTheMax = true;
57  			}
58  		}
59  		return allToTheMax == false;
60  	}
61  
62  	/**
63  	 * 
64  	 * @param indices
65  	 * @param maxIndices
66  	 * @return true if indices was successfully updates; false if there are no new
67  	 *         cases
68  	 */
69  	public int[] next() {
70  
71  		Validate.isTrue(hasNext());
72  
73  		boolean carryOver = true;
74  		int currentIndex = 0;
75  		while (carryOver && currentIndex < indices.length) {
76  
77  			indices[currentIndex] += 1;
78  
79  			if (indices[currentIndex] >= maxIndices[currentIndex] && currentIndex < indices.length - 1) {
80  				indices[currentIndex] = 0;
81  
82  				for (int j = 0; j < currentIndex; j++) {
83  					indices[j] = 0;
84  				}
85  
86  				currentIndex++;
87  				carryOver = true;
88  			} else {
89  				carryOver = false;
90  			}
91  
92  		}
93  
94  		return indices;
95  	}
96  
97  	@Override
98  	public int hashCode() {
99  		final int prime = 31;
100 		int result = 1;
101 		result = prime * result + Arrays.hashCode(indices);
102 		result = prime * result + Arrays.hashCode(maxIndices);
103 		return result;
104 	}
105 
106 	@Override
107 	public boolean equals(Object obj) {
108 		if (this == obj)
109 			return true;
110 		if (obj == null)
111 			return false;
112 		if (getClass() != obj.getClass())
113 			return false;
114 		MultiIntCounter other = (MultiIntCounter) obj;
115 		if (!Arrays.equals(indices, other.indices))
116 			return false;
117 		if (!Arrays.equals(maxIndices, other.maxIndices))
118 			return false;
119 		return true;
120 	}
121 
122 	@Override
123 	public String toString() {
124 		return "MultiIntCounter [indices=" + Arrays.toString(indices) + ", maxIndices=" + Arrays.toString(maxIndices)
125 				+ "]";
126 	}
127 }