C++ C++;多集,结构仅擦除一个,快速(过载?)
每个值为y的节点都将被删除,但我只希望值为y和索引为x的节点被删除 我通过手动操作解决了这个问题:C++ C++;多集,结构仅擦除一个,快速(过载?),c++,struct,multiset,C++,Struct,Multiset,每个值为y的节点都将被删除,但我只希望值为y和索引为x的节点被删除 我通过手动操作解决了这个问题: Nodes.erase(node (x, y)); for(std::multiset::iterator iter=Nodes.begin();iter!=Nodes.end();iter++){ 节点实际值\节点=*iter; if(实际_node.idx==to_delete.idx&&actual_node.value==to_delete.value){ 节点擦除(iter); } 返
Nodes.erase(node (x, y));
for(std::multiset::iterator iter=Nodes.begin();iter!=Nodes.end();iter++){
节点实际值\节点=*iter;
if(实际_node.idx==to_delete.idx&&actual_node.value==to_delete.value){
节点擦除(iter);
}
返回;
}
但这似乎有一个糟糕的表现。
我需要数百万个节点,我需要每一次加速。:)
有什么想法吗
好的,很好。我刚忘了把注销时的线路取下来。因此,每次更改集合后,都会创建一个日志并直接保存到磁盘。对此进行注释将时间从50秒减少到0,0x秒。足够快。:)
但不管怎么说,所有的回答都是错误的
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;
}
请注意,要使用std::remove(),必须包含算法头文件:
std::remove(std::begin(Nodes), std::end(Nodes),
[&to_delete]( struct node & x )
{
return ( x.idx == to_delete.idx &&
x.value == to_delete.value);
}
#包括
您可以通过某种方式获得元素的迭代器,该元素等于节点(x,y)
。然后,使用迭代器进行擦除将只删除一个元素
这就是说,使用这种比较函数,您将很难(在复杂性方面)找到节点(x,y)
,因为x
不能有效地搜索具有相同y
和不同x
的节点
一种解决方案是将比较函数更改为按y
排序,然后按x
排序,然后可能使用集合而不是多集合。
在这之后,如果您想要一个具有特定y
的元素,您可以使用类似于Nodes.lower_bound(node(-INFINITY,y))
的东西,它的复杂性为O(logn)。如何
std::多集节点;
插入(节点{1,10});
插入(节点{2,1});
插入(节点{3,1});
插入(节点{4100});
cout只需查看y
匹配的节点,就可以获得恒定因子的加速比
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";
}
或者没有C++17
auto [first, last] = Nodes.equal_range(to_delete);
auto it = std::find(first, last, to_delete);
if (it != last) {
Nodes.erase(it);
}
使用C++14,您可以通过node
或int
auto range = Nodes.equal_range(to_delete);
auto it = std::find(range.first, range.second, to_delete);
if (it != range.second) {
Nodes.erase(it);
}
struct节点{
int idx;//每个节点都有一个唯一的索引
int value;//不同的节点可以有相同的值
};
无结构节点{
使用透明=无效;
布尔运算符()(常量节点&a、常量节点&b)常量
{
返回std::tie(a.value,a.key)
您确定需要multiset吗?也许你需要另一个数据结构?你需要把你的代码< >操作器()/>代码>到“如果有一个领带与<代码> y>代码>,然后比较席思维,一个多集是最好的方法,现在它足够快。<代码>
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";
}
auto [first, last] = Nodes.equal_range(to_delete);
auto it = std::find(first, last, to_delete);
if (it != last) {
Nodes.erase(it);
}
auto range = Nodes.equal_range(to_delete);
auto it = std::find(range.first, range.second, to_delete);
if (it != range.second) {
Nodes.erase(it);
}
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