Supposons que l’utilisateur entre un tableau, par exemple:
Array = {France, Spain, France, France, Italy, Spain, Spain, Italy}
dont je connaissais la longueur
le tableau d’ index
serait:
index = {0, 1, 2, 3, 4, 5, 6, 7}
Maintenant, après le sorting en utilisant Arrays.sort(Array);
newArray
sera comme:
newArray = {France, France, France, Italy, Italy, Spain, Spain, Spain}
et le newIndex
sera:
newIndex = {0, 2, 3, 4, 7, 1, 5, 6}
Le problème est le suivant: comment puis-je trouver le newIndex
partir du tableau d’entrée?
Merci d’avance
Ne sortingez pas le tableau pour commencer. Triez le tableau d’index en transmettant un comparateur qui compare les valeurs en les utilisant comme index dans le tableau. Donc, vous vous retrouvez avec newIndex
comme résultat du sorting, et il est sortingvial d’aller de là au tableau sortingé d’éléments réels.
Certes, cela signifie sortinger un tableau d’entiers de manière personnalisée – ce qui signifie soit utiliser un Integer[]
et la bibliothèque Java standard, soit une bibliothèque tierce qui possède une interface “IntComparator” qui peut être utilisée avec un sort(int[], IntComparator)
type de méthode.
EDIT: Ok, voici un exemple de comparateur. Par souci de simplicité, je suppose que vous voulez seulement sortinger un tableau de chaînes “original” … et je ne me soucierai pas des tests de nullité.
public class ArrayIndexComparator implements Comparator { private final Ssortingng[] array; public ArrayIndexComparator(Ssortingng[] array) { this.array = array; } public Integer[] createIndexArray() { Integer[] indexes = new Integer[array.length]; for (int i = 0; i < array.length; i++) { indexes[i] = i; // Autoboxing } return indexes; } @Override public int compare(Integer index1, Integer index2) { // Autounbox from Integer to int to use as array indexes return array[index1].compareTo(array[index2]); } }
Vous l'utiliseriez comme ceci:
Ssortingng[] counsortinges = { "France", "Spain", ... }; ArrayIndexComparator comparator = new ArrayIndexComparator(counsortinges); Integer[] indexes = comparator.createIndexArray(); Arrays.sort(indexes, comparator); // Now the indexes are in appropriate order.
Un moyen concis d’y parvenir avec l’API Java 8 Stream,
final Ssortingng[] strArr = {"France", "Spain", "France"}; int[] sortedIndices = IntStream.range(0, strArr.length) .boxed().sorted((i, j) -> strArr[i].compareTo(strArr[j]) ) .mapToInt(ele -> ele).toArray();
TreeMap map = new TreeMap(); for( int i : indexes ) { map.put( ssortingngarray[i], i ); }
Maintenant, iterator sur map.values () pour récupérer les index dans l’ordre de sorting, et sur map.keySet () pour obtenir les chaînes, ou sur map.entrySet () pour obtenir les paires-index-chaîne.
J’ai fait ce qui suit sur la base du code de @ Skeet. Je pense que c’est un peu plus l’OOPie. Je ne sais pas.
public static > List sortIndex(List in) { ArrayList index = new ArrayList<>(); for (int i = 0; i < in.size(); i++) { index.add(i); } Collections.sort(index, new Comparator () { @Override public int compare(Integer idx1, Integer idx2) { return in.get(idx1).compareTo(in.get(idx2)); } }); return index; }
Au lieu de la classe qui implémente le sorting et l’indexation ayant le code Comparateur pour les différents objects entrant, les objects du tableau d’origine doivent implémenter l’interface Comparable. Il semble que de nombreux objects d’intérêt aient un ordre naturel et que l’interface Comparable soit déjà implémentée.
public static void main(Ssortingng[] args) { List a1 = new ArrayList<>(Arrays.asList(2, 3, 9, 4, 1)); // Just pass in the list to have its indexes sorted by the natural ordering List idx = sortIndex(a1); List a2 = new ArrayList<>(Arrays.asList(1.0, 5.3, 5.2, -3.1, 0.3)); idx = sortIndex(a2); List a3 = new ArrayList<>(); for (int i = 0; i < 10; i++) { a3.add(new numBits(i)); } // If you need to sort the indexes of your own object, you must implement // the Comparable Interface. idx = sortIndex(a3); } static class numBits implements Comparable { private int a; public numBits(int i) { a = i; } public Ssortingng toSsortingng() { return Integer.toSsortingng(a); } // Sort by the total number of bits in the number. @Override public int compareTo(numBits that) { if (Integer.bitCount(this.a) < Integer.bitCount(that.a)) return -1; if (Integer.bitCount(this.a) > Integer.bitCount(that.a)) return 1; return 0; } }
Pour ce faire, vous pouvez, entre autres, envelopper l’index et le nom de pays d’origine dans une classe distincte. Ensuite, sortingez le tableau en fonction des noms. De cette façon, vos index originaux seront préservés.
Si le scénario consiste à sortinger à plusieurs resockets des tableaux primitifs float ou int avec des valeurs positives, une méthode comme ci-dessous donne une vitesse bien meilleure (x3 ~ x4) que l’utilisation de comparateurs:
long time = System.currentTimeMillis(); for (int i = 0; i < iters; i++) { float[] array = RandomUtils.randomFloatArray(-1, 1, 3000); long[] valueKeyPairs = new long[array.length]; for (int j = 0; j < array.length; ++j) { valueKeyPairs[j] = (((long) Float.floatToIntBits(array[j])) << 32) | (j & 0xffffffffL); } Arrays.sort(valueKeyPairs); /**Then use this to retrieve the original value and index*/ //long l = valueKeyPairs[j]; //float value = Float.intBitsToFloat((int) (l >> 32)); //int index = (int) (l); } long millis = System.currentTimeMillis() - time;
Qu’est-ce qui vient au premier coup d’oeil est leur carte comme ça
Map map = new HashMap(); map.put(0, "France"); map.put(1, "Spain"); map.put(2, "France");
et ensuite les sortinger par valeur comme ça et ensuite vous pouvez connaître leurs index et leurs valeurs (clé, valeurs) simplement imprimer la carte
Iterator mapIterator = map.keySet().iterator(); while (mapIterator .hasNext()) { Ssortingng key = mapIterator.next().toSsortingng(); Ssortingng value = map.get(key).toSsortingng(); System.out.println(key + " " + value); }