【问题标题】:Priority Queue with custom comparator具有自定义比较器的优先级队列
【发布时间】:2016-09-18 23:34:49
【问题描述】:

我正在尝试使用优先级队列来保存具有以下成员变量的自定义对象:

class Jobs{
    string id;
    string location;
    int start;
    int end;
};

我将从文件中读取作业 ID 和作业权重的哈希图。我最终会有一个

unordered_map<string, int> jobWeight;

持有这些信息。我想最终将作业列表推送到 priority_queue 中,优先级基于 hashmap jobWeight。权重最高的工作应该排在第一位。

参考其他教程,我注意到您应该创建一个单独的类/结构并实现 operator()。然后,您会将这个比较类传递给 priority_queue 参数。但是,priority_queue 似乎使用默认参数创建了此比较器类的新实例?我如何能够从这个比较器类中引用我的 jobWeight 哈希图?

class CompareJobs{

    map<string, int> jobWeight;

public:

    CompareJobs(map<string, int> &jobWeight){
        jobWeight = jobWeight;
    }

    bool operator () (const Jobs &a, const Jobs &b){

        return jobWeight.find(a)->second < jobWeight.find(b)->second;

    }

};

【问题讨论】:

  • 您最初声明jobWeightunordered_map。您想将其转换为 map 并将其作为参数传递给您的比较器还是什么?
  • 此地图是否用于此比较器以外的其他用途?还有:它有多大?
  • @DanielJour 该地图只应在我插入优先级队列时用于比较。该地图将与工作数量一样大..(每个工作都会有一个权重)因此可能非常大。目前,最终目标是为每个时间范围选择一份工作(这些工作不必从头到尾持续整个持续时间......所以选择工作的贪婪方法应该足够了。我只是使用priority_queue 填满整个时间范围。

标签: c++ c++11 priority-queue


【解决方案1】:

我如何能够从这个比较器类中引用我的 jobWeight 哈希图?

在您的比较类中添加对地图的引用!当然,您需要确保此引用保持有效。而且您不能使用普通引用(因为这些引用不可复制,您的 Compare 类必须如此),而是可以使用 std::reference_wrapper

using IDMap = std::unordered_map<std::string, int>;

struct JobsByWeight {
  std::reference_wrapper<IDMap const> weights_ref;
  bool operator()(Job const & lhs, Job const & rhs) const {
    auto const & weights = weights_ref.get();
    auto lhsmapping = weights.find(lhs.id);
    auto rhsmapping = weights.find(rhs.id);
    if (lhsmapping == weights.end() || rhsmapping == weights.end()) {
      std::cerr << "damn it!" << std::endl;
      std::exit(1);
    }
    return lhsmapping->second < rhsmapping->second;
  }
};

然后只需将您的 Compare 类的一个对象传递给您的 priority queue's constructor(在链接中重载 (1)):

std::priority_queue<Job, std::vector<Job>, JobsByWeight> queue{std::cref(that_id_map)};

由于没有构造函数允许您在队列中移动 Compare 类,因此您确实需要在 JobsByWeight 中的引用。否则会有一份你的地图副本(如你所说,它可能很大)。

注意:未经测试的代码。

【讨论】:

  • 谢谢!从来没有意识到priority_queues带参数。
【解决方案2】:

std::priority_queue的默认构造函数实际上是带可选参数的:

explicit priority_queue(const Compare& x = Compare(), Container&& = Container());

您会注意到第一个参数是比较器类的一个实例。

首先构造您的比较器类,使其以您方便的任何方式引用您的哈希图,然后使用比较器类来构造您的优先级队列。

【讨论】:

  • 啊从来没有注意到这一点。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
相关资源
最近更新 更多