The result will be
Target positions: [1, 2, 3, 7, 8] Permutation: [0, 1, 2, 3, 4] Permutation: [0, 1, 2, 4, 3] Permutation: [0, 2, 1, 3, 4] Permutation: [0, 2, 1, 4, 3] Permutation: [1, 0, 2, 3, 4] Permutation: [1, 0, 2, 4, 3] Permutation: [1, 2, 0, 3, 4] Permutation: [1, 2, 0, 4, 3] Permutation: [2, 0, 1, 3, 4] Permutation: [2, 0, 1, 4, 3] Permutation: [2, 1, 0, 3, 4] Permutation: [2, 1, 0, 4, 3]
In this example it is clearly seen, that iterating goes over specified combinatorics over array of target indices. Each permutation permutes positions of target indices, and for iterating directly over target indices see wrapper class {@link PermutationsProviderWrapper}.
One of the useful using of {@code PermutationProvider} is to compare two arrays ( {@code arr1} and {@code arr2}). Let we have two arrays of objects, sorted, for example, by their hash code. First we shall compare them hash code arrays. Let that corresponding hash arrays are equals and looks like {1,3,5,6,6,6,7,9,11,11}. After comparing hash arrays we shall iterate over arrays {@code arr1} and {@code arr2} and consecutively compare corresponding elements. For elements with equals hash code we must try all combinatorics. In our example we must permute elements with hash code 6 and 11. We can construct {@code PermutationProvider} with target positions {3,4,5,8,9} and use it to provide such combinatorics. Illustration code below:
public PermutationProvider generateProvider(final Object[] array) // array is sorted by hashCode { int begin = 0; int i; ListdisjointProviders = new ArrayList<>(); for (i = 1; i < array.length; ++i) if (i == size() || array[i].hash() != array[i-1].hash()) { if (i - 1 != begin) disjointProviders.add(new SimplePermutationProvider(begin, i)); begin = i; } return new PermutationsProviderImpl(disjointProviders); } public boolean compareArrays(final Object[] array1, final Object[] array2) // arrays are sorted by hashCode { int size; if ((size = array1.length) != array2.length) return false; // if arrays are equals their providers are equals to PermutationsProvider provider = generateProvider(array1); int[] nonPermutablePositions = PermutationsProvider.Util.getNonpermutablePositions(size, provider); for (int i : nonPermutablePositions) if (!array1[i].equals(array2[i])) return false; int[] targetPositions = provider.targetPositions(); out_for: for (Permutation permutation : provider.allPermutations()) { for (int i = 0; i < targetPositions.length; ++i) if (!array1[targetPositions[i]].equals(array2[targetPositions[permutation.newIndexOf(i)]])) continue out_for; return true; } return false; }
NOTE: Implementations are not obliged to look after disjoint providers, so them target positions are really differs (disjoint). For example, {@code PermutationsProviderImpl} allows for disjoint providersto have parts with same target positions.
For more information see implementations and testing files. @see SimplePermutationProvider @see PermutationsProviderImpl @see PermutationsProviderWrapper @see EmptyPermutationsProvider @see TensorSortedContentImpl @author Dmitry Bolotin @author Stanislav Poslavsky
|
|