C++ priority_queue 带有自定义比较器并删除了任何项目
C++ priority_queue with custom comparator and removal of any item
我正在研究最小堆的解决方案,除了自定义比较器之外,它还需要支持删除任何元素。完全自定义的堆实现是一种方法。但是我想依靠 C++ STL 来进行所需的操作。
C++ 文档和 Whosebug 回答 here 指出我使用自定义 class 并重载自定义 remove
方法。我还在同一个 class.
中重载了自定义比较器
template<typename T>
class custom_priority_queue_MinHeap : public std::priority_queue<T, std::vector<T>>
{
public:
bool remove(const T& value)
{
auto it = std::find(this->c.begin(), this->c.end(), value);
if (it != this->c.end())
{
this->c.erase(it);
std::make_heap(this->c.begin(), this->c.end(), this->comp);
return true;
}
return false;
}
bool operator()(const pair<int, int> &a, const pair<int, int> &b)
{
cout << "Custom comparator called" << endl; <----------- Never called
return a.second > b.second;
}
};
自定义堆的消耗类似于:
custom_priority_queue_MinHeap<pair<int, int>> minHeap;
minHeap.push({0, 10});
minHeap.push({1, 5});
minHeap.push({2, 15});
while(!minHeap.empty())
{
pair<int, int> p = minHeap.top();
minHeap.pop();
cout << p.first << " " << p.second << endl;
}
当 Ideone 上的 运行 时,minHeap push
未按预期工作。它在输出下方闪烁:
2 15
1 5
0 10
正确的输出应该是:
1 5
0 10
2 15
()
比较器重载从未被调用,这似乎是罪魁祸首。元素按照插入的顺序弹出。有趣的是,remove
函数运行良好。
问题:
是否可以完全依赖 C++ priority_queue STL 来实现所需的操作,即支持删除任何元素的自定义比较器?如果是,我在上述实现中是否遗漏了什么?
感谢 PaulMcKenzie 为我指明了正确的方向!问题是 STL 中的 priority_queue 是三个参数 class。我的实现缺少第三个比较 class 参数。
以下更改效果很好。爱德华 link
class Comp
{
public:
bool operator()(const pair<int, int> &a, const pair<int, int> &b)
{
cout << "Custom comparator called" << endl;
return a.second > b.second;
}
};
template<typename T>
class custom_priority_queue_MinHeap : public std::priority_queue<T, std::vector<T>, Comp>
{
...
};
我正在研究最小堆的解决方案,除了自定义比较器之外,它还需要支持删除任何元素。完全自定义的堆实现是一种方法。但是我想依靠 C++ STL 来进行所需的操作。
C++ 文档和 Whosebug 回答 here 指出我使用自定义 class 并重载自定义 remove
方法。我还在同一个 class.
template<typename T>
class custom_priority_queue_MinHeap : public std::priority_queue<T, std::vector<T>>
{
public:
bool remove(const T& value)
{
auto it = std::find(this->c.begin(), this->c.end(), value);
if (it != this->c.end())
{
this->c.erase(it);
std::make_heap(this->c.begin(), this->c.end(), this->comp);
return true;
}
return false;
}
bool operator()(const pair<int, int> &a, const pair<int, int> &b)
{
cout << "Custom comparator called" << endl; <----------- Never called
return a.second > b.second;
}
};
自定义堆的消耗类似于:
custom_priority_queue_MinHeap<pair<int, int>> minHeap;
minHeap.push({0, 10});
minHeap.push({1, 5});
minHeap.push({2, 15});
while(!minHeap.empty())
{
pair<int, int> p = minHeap.top();
minHeap.pop();
cout << p.first << " " << p.second << endl;
}
当 Ideone 上的 运行 时,minHeap push
未按预期工作。它在输出下方闪烁:
2 15
1 5
0 10
正确的输出应该是:
1 5
0 10
2 15
()
比较器重载从未被调用,这似乎是罪魁祸首。元素按照插入的顺序弹出。有趣的是,remove
函数运行良好。
问题:
是否可以完全依赖 C++ priority_queue STL 来实现所需的操作,即支持删除任何元素的自定义比较器?如果是,我在上述实现中是否遗漏了什么?
感谢 PaulMcKenzie 为我指明了正确的方向!问题是 STL 中的 priority_queue 是三个参数 class。我的实现缺少第三个比较 class 参数。
以下更改效果很好。爱德华 link
class Comp
{
public:
bool operator()(const pair<int, int> &a, const pair<int, int> &b)
{
cout << "Custom comparator called" << endl;
return a.second > b.second;
}
};
template<typename T>
class custom_priority_queue_MinHeap : public std::priority_queue<T, std::vector<T>, Comp>
{
...
};