0

我在 C++ (gcc) 中有以下地图:

map<int, EdgeExtended> myMap;

其中 EdgeExtended 的定义是:

struct EdgeExtended {
    int neighborNodeId;
    int weight;
    int arrayPointer;
    bool isCrossEdge;

    EdgeExtended(Edge _edge, int _arrayPointer) {
        neighborNodeId = _edge.neighborNodeId;
        weight = _edge.weight;
        arrayPointer = arrayPointer;
        isCrossEdge = _edge.isCrossEdge;
    }

    EdgeExtended(const EdgeExtended & _edge) {
        neighborNodeId = _edge.neighborNodeId;
        weight = _edge.weight;
        arrayPointer = _edge.arrayPointer;
        isCrossEdge = _edge.isCrossEdge;
    }

    EdgeExtended(int _neighborNodeId, int _weight, bool _isCrossEdge, int _arrayPointer) {
        neighborNodeId = _neighborNodeId;
        weight = _weight;
        arrayPointer = _arrayPointer;
        isCrossEdge = _isCrossEdge;
    }

    void setValues(int _neighborNodeId, int _weight, bool _isCrossEdge, int _arrayPointer) {
        neighborNodeId = _neighborNodeId;
        weight = _weight;
        arrayPointer = _arrayPointer;
        isCrossEdge = _isCrossEdge;
    }

    EdgeExtended() {
        neighborNodeId = -1;
        weight = -1;
        arrayPointer = -1;
        isCrossEdge = false;
    }
};

我想这样做(简单的例子):

EdgeMap edge;
int nodeId=18;

edge=map.erase(nodeId);

a)此代码是否正确,擦除是否返回与键对应的对象?b) 如果是,当密钥不存在时,擦除返回什么?c)如果此代码错误,我如何检查是否存在键,对象映射到键,然后从映射中删除该对。请记住,性能相当关键,所以我需要最有效的方法。

4

3 回答 3

2

a) 不,这是不正确的。您调用的std::map::erase方法返回已擦除元素的数量。

您可以做的是使用std::map::find检查具有给定键的元素是否在地图中。如果元素存在,则返回一个迭代器,如果不存在则返回end()。您可以将此迭代器传递给相关的std::map::erase重载。

EdgeMap edge;
int nodeId=18;
ExtendedEdge removedEdge;
....
EdgeMap::iterator it = edge.find(nodeId);
if( it != edge.end() ) 
{
  // found element.
  removedEdge = it->second; // or removeEdge = std::move(it->second) in C++11
  edge.erase(it);
}
于 2013-02-06T20:32:36.033 回答
2

a)此代码是否正确,擦除是否返回与键对应的对象?

不,这将返回已删除的元素数。

b) 如果是,当密钥不存在时,擦除返回什么?

不适用。它只是返回0

c)如果此代码错误,我如何检查是否存在键,对象映射到键,然后从映射中删除该对。请记住,性能相当关键,所以我需要最有效的方法。

auto it = yourMap.find(nodeId);
if (it != yourMap.end()) {
   EdgeExtended theObjectToRemove = *it;
   yourMap.erase(it);
}

这与普通的复杂性相同erase(nodeId);,因为erase(it)需要摊销的常数时间。

于 2013-02-06T20:38:13.710 回答
1

我会用迭代器来做,像这样:

typedef map<int, EdgeExtended> EdgeMap;

bool RemoveEdge( EdgeMap & myMap, int nodeId, EdgeExtended &edge )
{
    EdgeMap::iterator e = myMap.find(nodeId);
    if( e == myMap.end() ) return false;
    edge = e->second;
    myMap.erase(e);
    return true;
}
于 2013-02-06T20:36:54.970 回答