web-dev-qa-db-fra.com

Explication sur Integer.MAX_VALUE et Integer.MIN_VALUE pour rechercher les valeurs min et max dans un tableau

Je ne semble pas comprendre comment Integer.MAX_VALUE et Integer.MIN_VALUE aide à trouver les valeurs min et max dans un tableau.

Je comprends comment cette méthode (pseudo-code ci-dessous) fonctionne pour trouver les valeurs min et max:

max = A[0], min = A[0]
for each i in A
  if A[i] > max then max = A[i]
  if A[i] < min then min = A[i] 

Mais pour cette méthode, je ne comprends pas le but de Integer.MAX_VALUE et Integer.MIN_VALUE:

import Java.util.Scanner;

class MyClass {

    public static void main(String[] args) {

        int[] numbers; // declaring the data type of numbers
        numbers = new int[3]; //assigning the number of values numbers will contain
        int smallest = Integer.MAX_VALUE, largest = Integer.MIN_VALUE;

        Scanner input = new Scanner(System.in);

        System.out.println("Please enter 3 numbers");

        for(int counter = 0; counter<numbers.length;counter++) {
            numbers[counter] = input.nextInt();
        }

        for(int i = 0; i<numbers.length; i++) {
            if(numbers[i]<smallest)
                smallest = numbers[i];
            else if(numbers[i]>largest)
                largest = numbers[i];
        }

        System.out.println("Largest is "+largest);
        System.out.println("Smallest is "+smallest);
    }

}
  • System.out.println (Integer.MAX_VALUE) donne 2147483647.
  • System.out.println (Integer.MIN_VALUE) donne -2147483648.

Alors, à quoi servent Integer.MIN_VALUE et Integer.MIN_VALUE dans les comparaisons?

25
Tia

mais en ce qui concerne cette méthode, je ne comprends pas le but d'Integer.MAX_VALUE et d'Integer.MIN_VALUE.

En commençant avec smallest défini sur Integer.MAX_VALUE et largest définis sur Integer.MIN_VALUE, ils ne doivent pas s’inquiéter plus tard du cas particulier où smallest et largest n’ont pas encore de valeur. Si les données que je consulte ont un 10 comme première valeur, puis numbers[i]<smallest sera vrai (parce que 10 est <Integer.MAX_VALUE) et nous mettrons à jour smallest pour qu'il soit 10. De même, numbers[i]>largest sera true parce que 10 est >Integer.MIN_VALUE et nous mettrons à jour largest. Etc.

Bien entendu, pour ce faire, vous devez vous assurer que vous disposez d'au moins une valeur dans les données que vous consultez. Sinon, vous vous retrouvez avec des nombres apocryphes dans smallest et largest.


Note le point Onome Sot fait dans les commentaires:

... si le premier élément du tableau est plus grand que le reste, le plus grand élément sera toujours Integer.MIN_VALUE en raison de l'instruction else-if.

Ce qui est vrai; Voici un exemple plus simple illustrant le problème ( live copy ):

public class Example
{
    public static void main(String[] args) throws Exception {
        int[] values = {5, 1, 2};
        int smallest = Integer.MAX_VALUE;
        int largest  = Integer.MIN_VALUE;
        for (int value : values) {
            if (value < smallest) {
                smallest = value;
            } else if (value > largest) {
                largest = value;
            }
        }
        System.out.println(smallest + ", " + largest); // 1, 2 -- WRONG
    }
}

Pour résoudre ce problème, soit:

  1. N'utilisez pas else, ou

  2. Commencez avec smallest et largest égaux au premier élément, puis mettez en boucle les éléments restants en conservant le else if.

Voici un exemple de ce second ( live copy ):

public class Example
{
    public static void main(String[] args) throws Exception {
        int[] values = {5, 1, 2};
        int smallest = values[0];
        int largest  = values[0];
        for (int n = 1; n < values.length; ++n) {
            int value = values[n];
            if (value < smallest) {
                smallest = value;
            } else if (value > largest) {
                largest = value;
            }
        }
        System.out.println(smallest + ", " + largest); // 1, 5
    }
}
31
T.J. Crowder

Au lieu d’initialiser les variables avec des valeurs arbitraires (par exemple, int smallest = 9999, largest = 0) il est plus sûr d’initialiser les variables avec les valeurs les plus grandes et les plus petites représentables par ce type de nombre (c’est-à-dire int smallest = Integer.MAX_VALUE, largest = Integer.MIN_VALUE).

Étant donné que votre tableau entier ne peut pas contenir une valeur supérieure à Integer.MAX_VALUE et plus petit que Integer.MIN_VALUE votre code fonctionne dans tous les cas Edge.

14
Salman A

En initialisant les valeurs min/max à l'extrême opposé, vous évitez les cas de valeurs Edge dans l'entrée: l'un des min/max est en fait une de ces valeurs (dans le cas où l'entrée ne comporte qu'une seule de ces valeurs ), ou le correct min/max sera trouvé.

Il est à noter que les types primitifs doivent ont une valeur. Si vous avez utilisé Objets (c.-à-d. Integer), vous pouvez initialiser la valeur sur null et gérer ce cas particulier pour la première comparaison, mais cela crée un code supplémentaire (inutile). Cependant, en utilisant ces valeurs, le code de la boucle n'a pas à s'inquiéter du cas Edge de la première comparaison.

Une autre alternative consiste à définir à la fois les valeurs initiales sur la première valeur du tableau en entrée (jamais un problème - voir ci-dessous) et d'effectuer une itération à partir de l'élément 2nd, puisqu'il s'agit du seul état correct de min/max. après une itération. Vous pouvez également effectuer une itération à partir du premier élément. Cela ne changerait rien si ce n’était de faire une itération supplémentaire (inutile) par rapport au premier élément.

La seule façon sensée de gérer l'inout de taille zéro est simple: jetez un IllegalArgumentException, car min/max n'est pas défini dans ce cas.

4
Bohemian