web-dev-qa-db-fra.com

obtenir la valeur la plus proche d'un nombre dans un tableau

J'ai un tableau d'ints positifs/négatifs

int[] numbers = new int[10];
numbers[0] = 100;
numbers[1] = -34200;
numbers[2] = 3040;
numbers[3] = 400433;
numbers[4] = 500;
numbers[5] = -100;
numbers[6] = -200;
numbers[7] = 532;
numbers[8] = 6584;
numbers[9] = -945;

Maintenant, je voudrais tester un autre int sur ce tableau et renvoyer le nombre le plus proche de l'int.

Par exemple, si j'utilisais le nombre 490, je récupérerais le numéro 4 des nombres 500, quel est le meilleur moyen de faire quelque chose comme cela?

int myNumber = 490;
int distance = 0;
int idx = 0;
for(int c = 0; c < numbers.length; c++){
    int cdistance = numbers[c] - myNumber;
    if(cdistance < distance){
        idx = c;
        distance = cdistance;
    }
}
int theNumber = numbers[idx];

Ça ne marche pas. Des suggestions sur une bonne méthode pour le faire?

19
Get Off My Lawn
int myNumber = 490;
int distance = Math.abs(numbers[0] - myNumber);
int idx = 0;
for(int c = 1; c < numbers.length; c++){
    int cdistance = Math.abs(numbers[c] - myNumber);
    if(cdistance < distance){
        idx = c;
        distance = cdistance;
    }
}
int theNumber = numbers[idx];

Initialisez toujours vos fonctions min/max avec le premier élément que vous envisagez. Utiliser des éléments tels que Integer.MAX_VALUE ou Integer.MIN_VALUE est un moyen naïf d’obtenir votre réponse; cela ne tient pas bien si vous changez les types de données plus tard (whoops, MAX_LONG et MAX_INT sont très différents!) ou si vous voulez, à l'avenir, écrire une méthode générique min/max pour le type de données any.

38
Chris Hayes

Dans Java 8 :

List<Integer> list = Arrays.stream(numbers).boxed().collect(Collectors.toList());

int n = 490;

int c = list.stream()
            .min(Comparator.comparingInt(i -> Math.abs(i - n)))
            .orElseThrow(() -> new NoSuchElementException("No value present"));

Initialement, vous pouvez utiliser une List au lieu de Array (les listes ont beaucoup plus de fonctionnalités).

7
Oleksandr

vous êtes très proche. Je pense que la valeur initiale de 'distance' devrait être un grand nombre au lieu de 0. Et utilisez la valeur absolue pour la distance. 

4
Don

cdistance = numbers[c] - myNumber. Vous ne prenez pas la valeur absolue de la différence. Si myNumber est beaucoup plus grand que numbers[c] ou si numbers[c] est négatif, la comparaison sera enregistrée comme "différence minimale".

Prenons par exemple le cas où numbers[c] = -34200. numbers[c] - myNumber serait alors -34690, beaucoup moins que le distance.

En outre, vous devez initialiser distance à une valeur élevée, car aucune solution n’a été trouvée au début.

2
irrelephant

Un bloc d'instructions pour initialiser et définir la correspondance la plus proche. De plus, renvoyez -1 si aucune correspondance la plus proche n’est trouvée (tableau vide). 

 protected int getClosestIndex(final int[] values, int value) {
    class Closest {
        Integer dif;
        int index = -1;
    };
    Closest closest = new Closest();
    for (int i = 0; i < values.length; ++i) {
        final int dif = Math.abs(value - values[i]);
        if (closest.dif == null || dif < closest.dif) {
            closest.index = i;
            closest.dif = dif;
        }
    }
    return closest.index;
}
1
farid_z

Je l'ai fait en tant que tâche pour mon cours et je l'ai programmé dans Ready to Program Java, alors veuillez m'excuser si c'est un peu déroutant.

// The "Ass_1_B_3" class.
import Java.awt.*;
import hsa.Console;

public class Ass_1_B_3
{
    static Console c;           // The output console

    public static void main (String[] args)
    {
        c = new Console ();

        int [] data = {3, 1, 5, 7, 4, 12, -3, 8, -2};
        int nearZero = 0;
        int temp = 0;
        int temp2 = data[0];

        for (int i = 0; i < data.length; i++)
        {
            temp = Math.abs (data[i]);
            nearZero = temp2;   
            if (temp < temp2)
            {
                temp2 = temp;
                nearZero = data[i];
            }


        }

        c.println ("The number closest to zero is: " + nearZero);

        // Place your program here.  'c' is the output console
    } // main method
} // Ass_1_B_3 class
0
DeadlySnipa999

Vous pouvez modifier la bonne vieille recherche binaire et la mettre en œuvre efficacement. 

Arrays.sort(numbers);
nearestNumber = nearestNumberBinarySearch(numbers, 0, numbers.length - 1, myNumber);

private static int nearestNumberBinarySearch(int[] numbers, int start, int end, int myNumber) {
    int mid = (start + end) / 2;
    if (numbers[mid] == myNumber)
        return numbers[mid];
    if (start == end - 1)
        if (Math.abs(numbers[end] - myNumber) >= Math.abs(numbers[start] - myNumber))
            return numbers[start];
        else
            return numbers[end];
     if(numbers[mid]> myNumber)
        return nearestNumberBinarySearch(numbers, start,mid, myNumber);
     else
         return nearestNumberBinarySearch(numbers,mid, end, myNumber);

}
0
Raj
public int getClosestToTarget(int target, int[] values) {

    if (values.length < 1)
        throw new IllegalArgumentException("The values should be at least one element");
    if (values.length == 1) {
        return values[0];
    }
    int closestValue = values[0];
    int leastDistance = Math.abs(values[0] - target);
    for (int i = 0; i < values.length; i++) {
        int currentDistance = Math.abs(values[i] - target);
        if (currentDistance < leastDistance) {
            closestValue = values[i];
            leastDistance = currentDistance;
        }
    }
    return closestValue;
}
0
Hamada Ibrahim