261 votes

Comment inverser un tableau d'int en Java ?

J'essaie d'inverser un tableau d'int en Java.

Cette méthode ne permet pas d'inverser le tableau.

for(int i = 0; i < validData.length; i++)
{
    int temp = validData[i];
    validData[i] = validData[validData.length - i - 1];
    validData[validData.length - i - 1] = temp;
}

Quel est le problème ?

34 votes

Je vois ce que j'ai fait de mal. Ça devrait être validData.length/2. Sinon, il s'inverse puis se dés-inverse.

4 votes

Voir fr.wikipedia.org/wiki/algorithme en place qui contient une description de la version correcte de cet algorithme.

0 votes

317voto

Manur Points 2652

Avec Commons.Lang vous pouvez simplement utiliser

ArrayUtils.reverse(int[] array)

La plupart du temps, il est plus rapide et plus sûr de s'en tenir à des bibliothèques facilement disponibles, déjà testées par l'unité et par l'utilisateur, lorsqu'elles prennent en charge votre problème.

5 votes

J'aurais préféré qu'il renvoie le tableau inversé (passé) pour un style plus fonctionnel.

2 votes

@laurent-g pour être juste : inverser le tableau de cette façon est plus efficace en termes de mémoire, ce qui est probablement la raison pour laquelle ils l'ont fait de cette façon.

8 votes

Mon propos n'était pas la copie ou la non copie. Mon message indique que "(passed)" doit être retourné (après avoir été inversé), de sorte qu'il pourrait être passé dans une expression, sans nécessiter une déclaration séparée.

312voto

3lectrologos Points 4673

Pour inverser un tableau d'int, vous permutez les éléments jusqu'à ce que vous atteigniez le point central, comme ceci :

for(int i = 0; i < validData.length / 2; i++)
{
    int temp = validData[i];
    validData[i] = validData[validData.length - i - 1];
    validData[validData.length - i - 1] = temp;
}

De la façon dont vous le faites, vous échangez chaque élément deux fois, de sorte que le résultat est le même que la liste initiale.

1 votes

Et je voudrais mettre validData.length / 2 à l'extérieur de la boucle for.

7 votes

@Jin Je ne le ferais pas. Cela ne fait qu'obscurcir le sens, et je parie que le compilateur optimiseur le ferait pour vous de toute façon. Quoi qu'il en soit, il n'y a aucun intérêt à micro-optimiser tant que vous n'avez pas la preuve évidente par le profilage que c'est nécessaire/utile.

9 votes

@JinKwon Ce serait un peu comme faire validData.length >> 1 . C'est équivalent et plus rapide, mais cela perturbe de nombreux programmeurs et tout bon compilateur le fera automatiquement.

57voto

Tarik Points 16118
public class ArrayHandle {
    public static Object[] reverse(Object[] arr) {
        List<Object> list = Arrays.asList(arr);
        Collections.reverse(list);
        return list.toArray();
    }
}

11 votes

Bien sûr que oui. Une liste ne peut contenir que des objets, pas des primitives, donc toutes les primitives ( int dans ce cas) sont intégrés dans leurs wrappers respectifs ( Integer dans ce cas) et les mettre dans la liste. Vous voyez, Integer sont des objets. @Tom

8 votes

Fais attention : Si je ne me trompe pas, le tableau original est modifié. Pour que ce soit clair, vous pouvez vouloir ne rien retourner.

1 votes

Comment convertir le tableau Object[] qu'il renvoie en tableau int[] ? ?? L'OP a posé la question pour un tableau d'ints, alors pourriez-vous s'il vous plaît donner le code qui fonctionne pour un tableau d'ints ? Merci.

43voto

Bill the Lizard Points 147311

Je pense qu'il est un peu plus facile de suivre la logique de l'algorithme si vous déclarez des variables explicites pour garder la trace des indices que vous échangez à chaque itération de la boucle.

public static void reverse(int[] data) {
    for (int left = 0, right = data.length - 1; left < right; left++, right--) {
        // swap the values at the left and right indices
        int temp = data[left];
        data[left]  = data[right];
        data[right] = temp;
    }
}

Je pense aussi que c'est plus lisible de faire ça dans une boucle while.

public static void reverse(int[] data) {
    int left = 0;
    int right = data.length - 1;

    while( left < right ) {
        // swap the values at the left and right indices
        int temp = data[left];
        data[left] = data[right];
        data[right] = temp;

        // move the left and right index pointers in toward the center
        left++;
        right--;
    }
}

0 votes

L'échange à l'ancienne semble plus facile, mais oui, lorsqu'il s'agit de valeurs d'index de tableau à gauche, à droite, ... cela sera utile pour le débogage, le cas échéant.

0 votes

Vous pourriez également ajouter 'public static void swap(int[] data, int index1, int index2) { ... } " et l'utiliser à partir de " reverse " comme ceci : swap(data, left, right).

5voto

AbsoluteBlue Points 21

Si vous travaillez avec des données plus primitives (par exemple char, byte, int, etc.), vous pouvez effectuer des opérations XOR amusantes.

public static void reverseArray4(int[] array) {
    int len = array.length;
    for (int i = 0; i < len/2; i++) {
        array[i] = array[i] ^ array[len - i  - 1];
        array[len - i  - 1] = array[i] ^ array[len - i  - 1];
        array[i] = array[i] ^ array[len - i  - 1];
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X