struct node {
int idx; // each node have a unique index
int value; // different nodes can have same value
}
struct node_help {
bool operator()(const node &a, const node &b) const
{
return a.value < b.value;
}
}
std::multiset<node, node_help> Nodes;
到目前为止一切顺利。现在我想从multiset中删除特定节点。当我使用它时:
Nodes.erase(node (x, y));
每个具有值y的节点都会被删除,但我只想删除具有值y 和索引x的节点。
我通过手动解决了这个问题:
for (std::multiset<node, node_comp>::iterator iter = Nodes.begin(); iter != Nodes.end(); iter++) {
node actual_node = *iter;
if (actual_node.idx == to_delete.idx && actual_node.value == to_delete.value) {
Nodes.erase(iter);
}
return;
}
但这似乎表现不佳。 我有数以百万计的节点,我需要每一次加速。 :) 有什么想法吗?
好的一切都好。我只是忘了带着注销的线条。因此,在集合中的每次更改之后,都会创建一个日志并将其直接保存到磁盘。评论这个将时间从50秒减少到0,0秒。足够快。 :) 但是对于所有的反应,无论如何都要。
答案 0 :(得分:0)
struct node_help {
bool operator()(const node &a, const node &b) const
{
return a.value <= b.value; // changes the equality check
}
}
如果您有C ++ 11,您可以按如下方式定义lambda并使其成为更好的代码。否则,您可能需要使用函数对象代替lambda。
std::remove(std::begin(Nodes), std::end(Nodes),
[&to_delete]( struct node & x )
{
return ( x.idx == to_delete.idx &&
x.value == to_delete.value);
}
请注意,要使用std :: remove(),您必须包含算法头文件:
#include<algorithm>
答案 1 :(得分:0)
您可以以某种方式获得等于node (x, y)
的元素的迭代器。然后,使用迭代器擦除将只删除一个元素。
也就是说,使用这样的比较函数,无论如何都会遇到一些问题(就复杂性而言)node (x, y)
,因为具有相同y
和不同x
的节点效率不高可以通过x
搜索。
一种解决方案是将比较函数更改为y
,然后按x
,然后使用集合而不是多集。
之后,如果您想要一个具有特定y
的元素,您可以使用具有复杂度O(log n)的Nodes.lower_bound (node (-INFINITY, y))
之类的内容。
答案 2 :(得分:0)
how about
std::multiset<node, node_help> Nodes;
Nodes.insert(node{ 1, 10 });
Nodes.insert(node{ 2, 1 });
Nodes.insert(node{ 3, 1 });
Nodes.insert(node{ 4, 100 });
cout << "before\n";
for (const auto& n : Nodes)
{
cout << n.idx << " " << n.value << "\n";
}
auto it = Nodes.find(node{ 0,1 });
while(it != Nodes.end())
{
Nodes.erase(it);
it = Nodes.find(node{ 0,1 });
}
cout << "\nafter\n";
for (const auto& n : Nodes)
{
cout << n.idx << " " << n.value << "\n";
}
答案 3 :(得分:0)
仅查看y
匹配的节点即可获得恒定的因子加速
auto [first, last] = Nodes.equal_range(to_delete);
auto it = std::find(first, last, to_delete);
if (it != last) {
Nodes.erase(it);
}
或者没有C ++ 17
auto range = Nodes.equal_range(to_delete);
auto it = std::find(range.first, range.second, to_delete);
if (it != range.second) {
Nodes.erase(it);
}
使用C ++ 14,您可以通过node
或int
来搜索节点
struct node {
int idx; // each node have a unique index
int value; // different nodes can have same value
};
struct node_less {
using is_transparent = void;
bool operator()(const node &a, const node &b) const
{
return std::tie(a.value, a.key) < std::tie(b.value, b.key);
}
bool operator()(int a, const node &b) const
{
return a < b.value;
}
bool operator()(const node &a, int b) const
{
return a.value < b;
}
};
std::set<node, node_less> Nodes;
Nodes.find(node{ x, y }); // single node
Nodes.equal_range(y); // all nodes that match y