-3

I have a homework assignment that and I am completely stuck (level: beginner).

I have to create a method that finds 3 closest distances from an user entry and all the points in an array - and I am stuck here.

The method is: public static int[] troisPlusProches (int x, int y, int[] coordonneesHabitations) where int x and int y are user entries, and the array int[] coordonneesHabitations is int[] coordonneesHabitations = {9, 30, 18, 8, 3, 18, 25, 36}. So the points are (9,30), (18,8), (3,18) and (25,36).

I used the formula: distance = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2))) to calculate the distances.

And now i have to find 3 shortest distances from an user entries and return their positions in a new array.

So if the user entries are x=10, y=15.

The shortest distance is 7.616 from a point (3, 18), the next one is 10.630 from a point (18, 8), and the third one is 15.033 from a point (9, 30). In this case the method should return an array int[] troisPlusProches = {3, 18, 18, 8, 9, 30}.

I know what I have to do, I just can't figure out how...

Here's one of the many wrong attempts:

public static int[] troisPlusProches (int x, int y, int[] (coordonneesHabitations) 
{
    int [] that = Arrays.copyOf(coordonneesHabitations, coordonneesHabitations.length);
    int table[] = new int[6];
    double distanceA = 0.0; 
    double minDistance = Float.MAX_VALUE;
    int a = 0;
    int b = 0;
    int i = 0;
    double ignore = Float.MAX_VALUE;
    double ignore2 = Float.MAX_VALUE;

    for (i = 0; i < that.length; i += 2) {
           a = that[i];
           b = that[i+1]; 
           distanceA = calculerDistance(a, b, x, y);
           if (distanceA < minDistance) { 
               minDistance = distanceA;
               table[0] = a;
               table[1] = b;
           }
       }
    ignore = minDistance;


    for (i = 0; i < that.length; i += 2) {
           a = that[i];
           b = that[i+1]; 
           distanceA = calculerDistance(a, b, x, y);
           if (distanceA == ignore) {
               continue; 
               }
           if (distanceA < minDistance) { 
               minDistance = distanceA;
               table[2] = a;
               table[3] = b;
               } 
           }
    ignore2 = minDistance;

    for (i = 0; i < that.length; i += 2) {
           a = that[i];
           b = that[i+1]; 
           distanceA = calculerDistance(a, b, x, y);
           if ((distanceA == ignore) || (distanceA == ignore2)) {
               continue; 
               }
           if (distanceA < minDistance) { 
               minDistance = distanceA;
               table[2] = a;
               table[3] = b;
               } 
           }

    return table; 
    }
Frenchie
  • 19
  • 4
  • 2
    Regarding this task: My 3rd task is to create a method and find 3 closest distances from an user entry and all the points in an array - and I am stuck here for 2 days now. Given this is a homework assignment good advice is to code it brute force and then optimize later. So given a user entry find the distance to each and every other point and then sort and take the 3 smallest. – mba12 Oct 19 '16 at 20:09
  • I'll post what I did in the next answer, it's pretty much what I've been doing the whole time. But I don't get the results for the 2nd and 3rd distance. I've tried to put it in one loop, I've tried 3 separate loops (like in the example below). I tried to loop within a loop... But still no results ;( – Frenchie Oct 20 '16 at 18:37
  • You need to reset `minDistance` to `Float.MAX_VALUE` before looking for the second and third point. Otherwise it will never find anything because all of the points are greater distance than the old min distance. – nhouser9 Oct 21 '16 at 18:58

2 Answers2

1

I don't speak french so I find it hard to read your code. However, think about it like this:

Tou have a method which computes the closest point to a user entry. Now you need to create a copy of that method which allows you to compute the closest point to a user entry excluding the point you already found. That will let you find the first and second closest points. Then do the same thing to find the third point, this time by excluding the two points you already found.

You can make a copy of your existing method. It might look something like this:

public static int plusProche (int x, int y, int[] coordonneesHabitations, int ignoreIndex) {
    double distanceA = 0.0; 
    int k = x;
    int z = y;
    int a = 0;
    int b = 0;
    int [] that = Arrays.copyOf(coordonneesHabitations, coordonneesHabitations.length); 
    int taille = that.length;
    int i = 0;
    double minDistance = Float.MAX_VALUE;
    int position = 0;

       for (i = 0; i < taille; i += 2) {

           //here we add the ability to skip the passed index
           if ((i / 2) == ignoreIndex) {
               continue;
           }

           a = that[i];
           b = that[i+1]; 
           distanceA = calculerDistance(a, b, k, z);
           if (distanceA < minDistance) { 
               minDistance = distanceA;
               position = i/2;
               System.out.println(i + " " + minDistance);
           }
       }
       return position;
}

You can use the above to find the second closest point, by passing the index of the closest point as an argument. It will skip that index, therefore finding the next closest index. Do something similar to find the third closest point.

nhouser9
  • 6,730
  • 3
  • 21
  • 42
  • Yeah, I was looking for something like this... I'll try it, thank you very much. – Frenchie Oct 19 '16 at 20:37
  • @Frenchie Happy to help. If it works please upvote and accept. If not let me know – nhouser9 Oct 19 '16 at 20:39
  • I have just 1 follow up question, what value does ignoreIndex have? I knew what I have to do from the beginning, I just don't know how to exclude the first value from the second search... Thank you once again. – Frenchie Oct 20 '16 at 18:00
  • @Frenchie The ignoreIndex should be the index of the closest point, which you already know how to find. Then the method will skip over the closest point, finding the second closest point. If this was helpful please also remember to upvote and accept =] – nhouser9 Oct 20 '16 at 18:05
  • I'll post what I did in the next answer, it's pretty much what I've been doing the whole time. But I don't get the results for the 2nd and 3rd distance. I've tried to put it in one loop, I've tried 3 separate loops (like in the example below). I tried to loop within a loop... But still no results ;( – Frenchie Oct 20 '16 at 18:37
  • @Frenchie when you run the example below what do you get back? I see one error right away: `if ((distanceA == ignore) && (distanceA == ignore2)) {` should be `if ((distanceA == ignore) || (distanceA == ignore2)) {`. Also this can get errors if there is a tie for the first or second distance. There may be more issues too. Post the output of the method below and we will work through it. – nhouser9 Oct 20 '16 at 20:06
  • Hi, I edited the original question, I hope it is more clear now. I know that this is wrong, the result is always 0 for the second and third count... – Frenchie Oct 21 '16 at 12:09
0

There's a solution that works, in case someone might need it...

public static int[] troisPlusProches (int x, int y, int[] coordonneesHabitations) 
{
    LinkedList<Integer> resultArray = new LinkedList<Integer>();
    int[] origArr = Arrays.copyOf(coordonneesHabitations, coordonneesHabitations.length);
    while (resultArray.size() < 6) {
        int positionInArray = Decharge.plusProche(x, y, origArr);
        LinkedList<Integer> newArr = new LinkedList<Integer>();
        for (int i = 0; i < origArr.length; i = i + 2) {
            if (i != positionInArray * 2) {
                newArr.add(origArr[i]);
                newArr.add(origArr[i + 1]);
            } else {
                resultArray.add(origArr[i]);
                resultArray.add(origArr[i + 1]);
            }
        }
        origArr = new int[newArr.size()];
        for (int k = 0; k < origArr.length; k++) {
            origArr[k] = newArr.get(k);
        }
    }
    int[] intResultArray = new int[resultArray.size()];
    for (int l = 0; l < intResultArray.length; l++) {
        intResultArray[l] = resultArray.get(l);
    }
    return intResultArray;
Frenchie
  • 19
  • 4