当前位置: 首页 > 知识库问答 >
问题:

正确使用Cpriority_queue比较器

左丘曦
2023-03-14

这个问题最近在一次采访中被问到。

public interface PointsOnAPlane {

/**
 * Stores a given point in an internal data structure
 */
void addPoint(Point point);

/**
 * For given 'center' point returns a subset of 'm' stored points that are
 * closer to the center than others.
 *
 * E.g. Stored: (0, 1) (0, 2) (0, 3) (0, 4) (0, 5)
 *
 * findNearest(new Point(0, 0), 3) -> (0, 1), (0, 2), (0, 3)
 */
vector<Point> findNearest(vector<Point> points, Point center, int m);

}

这是我使用的以下方法

1)创建一个最大堆priority_queue来存储最近的点priority_queue

2)迭代点向量,如果优先级队列大小,则推送一个点

3)如果size == m,则将队列顶部与当前点进行比较,并在必要时弹出

for(int i=0;i<points.size();i++)
{
    if(pq.size() < m)
    {
       pq.push(points[i]);
    } 
    else
    {
       if(compareDistance(points[i],pq.top(),center))
       {
         pq.pop();
         pq.push(points[i]);
       }
    }
}

4) 最后,将优先级队列的内容放入向量并返回。

我应该如何编写comp和compareDistance比较器,以允许我最初存储m个点,然后将当前点与顶部的点进行比较?


共有1个答案

拓拔富
2023-03-14

我认为您的方法可以改变,以便以不同的方式使用priority_queue。代码变得有点复杂,因为for循环中有一个if语句,并且这个if语句控制何时添加priority_queue。为什么不先将所有点添加到priority_queue,然后弹出m点?让priority_queue完成所有工作。

使用<code>priority_queue</code>实现<code>findNearest</code>功能的关键在于实现比较器可以是捕获中心参数的lambda。所以你可以这样做:

#include <queue>
#include <vector>
using namespace std;

struct Point { int x, y; };

constexpr int distance(const Point& l, const Point& r)
{
    return (l.x - r.x)*(l.x - r.x) + (l.y - r.y)*(l.y - r.y);
}

vector<Point> findNearest(const vector<Point>& points, Point center, int m)
{
    auto comparator = [center](const Point& l, const Point& r) {
        return distance(l, center) > distance(r, center);
    };

    priority_queue<Point, vector<Point>, decltype(comparator)> pq(comparator);

    for (auto&& p : points) {
        pq.emplace(p);
    }

    vector<Point> result;
    for (int i = 0; i < m; ++i) {
        result.push_back(pq.top());
        pq.pop();
    }

    return result;
}

在面试环境中,谈论算法中的缺陷也很好。

  • 这个实现在O(nlogng)中运行。将会有一个聪明的算法来击败这个运行时间,特别是因为您只需要最近的m点。
  • 由于队列的原因,它使用了O(n)更多的空间,我们应该能够做得更好。这个函数中真正发生的是一个排序,排序可以就地实现。
  • 容易发生整数溢出。一个好主意是在Point结构上使用模板。您还可以使用模板使point容器在findNeest函数中通用。容器只需要支持迭代。
 类似资料:
  • 我正在尝试为std::proirity\u队列实现我自己的密钥比较器,如下所示: 但它的给出错误: 在lambda函数中:第10行:Char 23:错误:将“const std::map”作为“this”参数传递将丢弃限定符[-fppermissive]返回m[a]

  • 问题内容: 我在db中有类型的字段。我使用PostgreSQL。和查询 不返回行中的值是。 但是例如查询 正常工作。 如何解决此问题并获取行? 问题答案: 要 解决 您的问题,请改用数据类型 ,该数据类型不是浮点类型,而是任意精度类型。 如果将数字文字 输入到(相同的单词,不同的含义)列中,则会存储 确切的 数量- 与a或column列不同,在该列中,值被强制为下一个可能的二进制近似值。这可能是正

  • 我对collection.sort()方法有一些问题。 Java . lang . illegalargumentexception:比较法违反了它的通用契约! 位于Java . util . Tim sort . merge lo(Tim sort . Java:747) at java.util.TimSort.mergeAt(TimSort.java:483) 位于java.util.Tim

  • 此项目是一个可编辑的字典程序。我正在尝试循环浏览已添加到词典中的单词,并将用户通过扫描仪输入的单词与已添加的单词进行比较。我的问题是,无论输入多么准确,我创建的异常总是被调用。我不确定异常是否错误,或者字符串是否比较不正确。字典中的单词是从一个名为“dictionary.txt”的文件中读取的。如果有帮助,程序将使用输入/输出。这是代码。。。。请帮忙!!

  • 我有以下课程: 这编译没有问题。但是,如果我尝试像这样内联变量: 我发现以下编译错误: 如何编写此表达式以使Java正确理解参数?

  • 我的列表中有这样一个< code>compareTo代码: 当我使用时,我得到以下错误: 当我将其更改为<code>if(this.long1 现在,重复确实发生了,需要正确排序。重复项是出现在第一个还是最后一个并不重要,只要它们按顺序正确分组,如下所示: 我该如何正确地做到这一点?谢谢你。 更新 该列表仍在按以下所有建议排序。这是因为它是一个