Search code examples
c++sortingstructgrahams-scan

Struct comparator accessing another field in c++


I am trying to implement Graham scan, and I want to do something like this:

private static void sortByPolar(Point[] points, Point r) {
    Arrays.sort(points, (p, q) -> {
    int compPolar = ccw(p, r, q);
    int compDist = dist(p, r) - dist(q, r); 
    return compPolar == 0 ? compDist : compPolar;
});

where Point r is the bottommost point. However, I am struggling to implement this same idea in c++ because I can only pass in the function of compar and I don't know how that can access the lowest point.

struct compar {
  vector<vector<int>> lowest;
  bool operator()(vector<int> const& a, vector<int> const& b) {
    cout<<lowest[0]<<endl;    // throws an error, how do I get this function access to lowest?
    return // TODO;
  }
};

// in another function:
sort(points.begin(), points.end(), compar());

Solution

  • You can give compar a constructor, with a parameter for the data you want, then just pass it in as an argument when you create the temporary instance:

    struct compar {
      explicit compar(vector<int> const& lowest) : m_lowest(lowest) {}
      
      bool operator()(vector<int> const& a, vector<int> const& b) {
        cout<<m_lowest[0]<<endl;
        return // TODO;
      }
    
    private:
      vector<int> m_lowest;
    };
    
    // in another function:
    vector<int> lowestPoint;  // (get this from somewhere)
    sort(points.begin(), points.end(), compar(lowestPoint));
    

    By the way, a whole vector just for two ints for every point seems pretty wasteful, and it's also not very descriptive. Why not make a nice Point type?

    struct Point
    {
       int x, y;
    };
    
    struct PointComparator
    {
       explicit PointComparator(const Point& lowest)
          : m_lowest(lowest)
       {}
       
       bool operator()(const Point& a, const Point& b)
       {
          std::cout << m_lowest[0] << std::endl;
          return; // TODO
       }
    
    private:
       Point m_lowest;
    };
    
    // in another function:
    Point lowestPoint;  // (get this from somewhere)
    std::sort(points.begin(), points.end(), PointComparator(lowestPoint));