C++ C++;多集,结构仅擦除一个,快速(过载?)

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); } 返

每个值为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);
}
返回;
}
但这似乎有一个糟糕的表现。 我需要数百万个节点,我需要每一次加速。:) 有什么想法吗

好的,很好。我刚忘了把注销时的线路取下来。因此,每次更改集合后,都会创建一个日志并直接保存到磁盘。对此进行注释将时间从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