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 cases
67  	 */
68  	public int[] next() {
69  
70  		Validate.isTrue(hasNext());
71  
72  		boolean carryOver = true;
73  		int currentIndex = 0;
74  		while (carryOver && currentIndex < indices.length) {
75  
76  			indices[currentIndex] += 1;
77  
78  			if (indices[currentIndex] >= maxIndices[currentIndex] && currentIndex < indices.length - 1) {
79  				indices[currentIndex] = 0;
80  
81  				for (int j = 0; j < currentIndex; j++) {
82  					indices[j] = 0;
83  				}
84  
85  				currentIndex++;
86  				carryOver = true;
87  			} else {
88  				carryOver = false;
89  			}
90  
91  		}
92  
93  		return indices;
94  	}
95  
96  	@Override
97  	public int hashCode() {
98  		final int prime = 31;
99  		int result = 1;
100 		result = prime * result + Arrays.hashCode(indices);
101 		result = prime * result + Arrays.hashCode(maxIndices);
102 		return result;
103 	}
104 
105 	@Override
106 	public boolean equals(Object obj) {
107 		if (this == obj)
108 			return true;
109 		if (obj == null)
110 			return false;
111 		if (getClass() != obj.getClass())
112 			return false;
113 		MultiIntCounter other = (MultiIntCounter) obj;
114 		if (!Arrays.equals(indices, other.indices))
115 			return false;
116 		if (!Arrays.equals(maxIndices, other.maxIndices))
117 			return false;
118 		return true;
119 	}
120 
121 	@Override
122 	public String toString() {
123 		return "MultiIntCounter [indices=" + Arrays.toString(indices) + ", maxIndices=" + Arrays.toString(maxIndices)
124 				+ "]";
125 	}
126 }