c++arrayspointclosest

Find closest point from array


I try make table using array for example table like this

int array[5][3] = { {A, 200, 400}, {B, 300, 600}, {C, 100, 200}, {D, 200, 100}, {E, 200, 400} };

so array output will be like this :

| id |  X  |  Y  |
| A  | 200 | 400 | //First Row
| B  | 300 | 600 | //Second Row
| C  | 100 | 200 |
| D  | 300 | 100 |
| E  | 200 | 400 |

at this case example i have value :

int valueid = null; int valueX = 150; int valueY = 170;

so at this Case Nearest Point from table is ID C from table to my value.

my question is how to find nearest closet point from array table

I know only find sqrt for single row :

int cx = array[0][1] - valueX;
int cy = array[0][2] - valueY;
int FindClosest = sqrt(cx * cx + cy * cy);

how to count closest point from array table at code above only calculate closet point from First Row how to calculate from all row and print the result?


Solution

  • The standard library has an algorithm section with all kinds of functions for commonly used algorithms that are tested and reusable. For your problem that would be std::min_element. To make min_element work in a readable way is model your points as Point (class/struct), not some multidimensional integer array (in which indices are used to represent x and y and an id). After you've modeled a Point, you can make an array (or vector) of those. The next step is to get std::min_element working by providing a compare function : which usually is provided in terms of a lambda expression.

    Demo :https://onlinegdb.com/itNV7M3nG

    #include <vector>
    #include <cmath>
    #include <string>
    #include <algorithm>
    #include <iostream>
    
    // Do NOT use `int array[5][3]` thats a semantically meaningless thing
    // only showing HOW you are implementing things, but missing the point
    // of describing what you are doing. That will make code hard to read
    
    // So lets introduce a struct to represent a point in your array
    // and a function to calculate distance between two of your points
    
    struct Point
    {
        std::string name;
        int x;
        int y;
    
        double distance(const Point& other) const
        {
            return std::sqrt((x - other.x) * (x - other.x) + (y - other.y) * (y - other.y));
        }
    };
    
    // https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt
    // print Point to output stream
    std::ostream& operator<<(std::ostream& os, const Point& point)
    {
        os << "`" << point.name << "(" << point.x << "," << point.y << ")`";
        return os;
    }
    
    int main()
    {
        // resizable array (std::vector)    
        std::vector<Point> points{ { "A", 0, 0 }, { "B", 2, 2 }, { "C", 5, 5 }, { "D", 9, 9 } };
    
        // The point you want to find the closest point to
        Point somePoint{ "X", 3, 3 };
    
        // https://en.cppreference.com/w/cpp/algorithm/min_element
        // https://en.cppreference.com/w/cpp/language/lambda
        auto it = std::min_element(points.begin(), points.end(), 
            // Lambda expression : Capture `somePoint` by reference and then make a compare function that compares distance to `somePoint`for two points in the input
            [&](const Point& a,const Point& b) 
            { 
                return a.distance(somePoint) < b.distance(somePoint); 
            });
    
        // it is now an iterator referencing the closest point to `somePoint`
        std::cout << "Closest point to " << somePoint << " is " << *it << "\n";
    }
    

    Disclaimer, this is bit of a brute force approach. It will recalculate distances (it could have seen before), I focused more on showing C++ style coding.