结构擦除的C ++ multiset只有一个,快(重载?)

时间:2015-04-24 17:06:42

标签: c++ struct multiset

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秒。足够快。 :) 但是对于所有的反应,无论如何都要。

4 个答案:

答案 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,您可以通过nodeint来搜索节点

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