View Javadoc
1   package net.bmahe.genetics4j.core.util;
2   
3   import java.util.Arrays;
4   import java.util.Objects;
5   
6   import org.apache.commons.lang3.Validate;
7   
8   public class MultiIntCounter {
9   
10  	final int[] indices;
11  	final int[] maxIndices;
12  
13  	public MultiIntCounter(final int... maxIndices) {
14  		Objects.requireNonNull(maxIndices);
15  		Validate.isTrue(maxIndices.length > 0);
16  
17  		for (int i = 0; i < maxIndices.length; i++) {
18  			final int maxIndex = maxIndices[i];
19  			Validate.isTrue(maxIndex > 0);
20  		}
21  
22  		this.indices = new int[maxIndices.length];
23  		this.maxIndices = Arrays.copyOf(maxIndices, maxIndices.length);
24  	}
25  
26  	public int[] getIndices() {
27  		return indices;
28  	}
29  
30  	public int getIndex(final int index) {
31  		Validate.isTrue(index >= 0);
32  		Validate.isTrue(index < indices.length);
33  
34  		return indices[index];
35  	}
36  
37  	public int[] getMaxIndices() {
38  		return maxIndices;
39  	}
40  
41  	public int getTotal() {
42  		int total = 1;
43  		for (int i : maxIndices) {
44  			total *= i;
45  		}
46  		return total;
47  	}
48  
49  	public boolean hasNext() {
50  
51  		/**
52  		 * Precondition check if we tried all the combinations
53  		 */
54  		boolean allToTheMax = false;
55  		for (int i = 0; i < indices.length && !allToTheMax; i++) {
56  			if (indices[i] >= maxIndices[i]) {
57  				allToTheMax = true;
58  			}
59  		}
60  		return allToTheMax == false;
61  	}
62  
63  	/**
64  	 * 
65  	 * @param indices
66  	 * @param maxIndices
67  	 * @return true if indices was successfully updates; false if there are no new 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 		return prime * result + Arrays.hashCode(maxIndices);
103 	}
104 
105 	@Override
106 	public boolean equals(Object obj) {
107 		if (this == obj) {
108 			return true;
109 		}
110 		if (obj == null) {
111 			return false;
112 		}
113 		if (getClass() != obj.getClass()) {
114 			return false;
115 		}
116 		MultiIntCounter other = (MultiIntCounter) obj;
117 		if (!Arrays.equals(indices, other.indices)) {
118 			return false;
119 		}
120 		return Arrays.equals(maxIndices, other.maxIndices);
121 	}
122 
123 	@Override
124 	public String toString() {
125 		return "MultiIntCounter [indices=" + Arrays.toString(indices) + ", maxIndices=" + Arrays.toString(maxIndices)
126 				+ "]";
127 	}
128 }