Rgd:Vector Iterator获取索引位置

时间:2013-02-17 08:30:44

标签: c++

这是我的迭代器位置代码

struct node {
int nodeid;
vector<fingerTable> fTable;
vector<string> data;
};

vector<node> cNode;

vector<node>::iterator position = find(cNode.begin(),cNode.end(), id);

我有大约100个对象,我试图找到例如nodeid“80”的索引/元素/位置,假设我的对象都是由nodeid以升序排序。

我担心的是速度和内存使用情况,我之前使用的是

for(int i=0;i<cNode.size();i++)
{
//if logic-- match nodeid with the nodeid input.. then assign the i to an integer..
}

但现在我正在尝试使用和迭代器,我听到它更快..任何关于修复它的建议或者是否有更好的方法通过其值“nodeid”找到我的矢量索引

我知道地图对于我的情况来说是一个很好的标准容器,但是我有点没时间做更改所以我必须坚持使用矢量..

vector<node>::iterator position = find(cNode.begin(),cNode.end(), id);

当我尝试编译上面的迭代器行时输出错误。

In member function ‘void chord::removePeer(int)’:
testfile.cpp:532:69: error: no matching function for call to ‘chord::find(std::vector<chord::node>::iterator, std::vector<chord::node>::iterator, int&)’
testfile.cpp:532:69: note: candidate is:
testfile.cpp:177:5: note: int chord::find(int, int, bool)
testfile.cpp:177:5: note:   no known conversion for argument 1 from ‘std::vector<chord::node>::iterator {aka __gnu_cxx::__normal_iterator<chord::node*, std::vector<chord::node> >}’ to ‘int’

3 个答案:

答案 0 :(得分:1)

你有一个对象矢量。每个对象都包含一个int。您正试图“找到”该向量中的对象,该对象在该int中具有给定值。但编译器不理解这一点,因为STL仅描述了如何在容器中查找值。怎么可能不是这样呢?如果你有一个包含两个整数的对象,哪一个会被比较?

既然你说使用std::find()是为了比老式for循环更好的表现,你现在可以停止尝试,然后再回过头来看看。两种方式的表现基本相同,你已经说过你已经没时间了。所以只需使用你的工作,因为它不是性能问题。

如果您坚持使用迭代器,则可以将std::find_if()与您定义的自定义谓词一起使用,如下所示:

struct HasId {
    HasId(int id) : _id(id) {}
    bool operator()(node const& n) const { return n.nodeid == _id; }
private:
    int _id;
}

std::find_if(cNode.begin(), cNode.end(), HasId(id));

这样,我们提供了足够的信息让STL找到我们感兴趣的元素,而无需创建要搜索的临时节点。

答案 1 :(得分:0)

cNode是node类型的向量,但是你传入id(int类型),你需要一个隐式转换函数来将id转换为node对象:

struct node {
   int nodeid;
   vector<fingerTable> fTable;
   vector<string> data;

    node(int id)
    : nodeid(nodeid)
    {
    }
};

bool operator==(const node& lhs, const node& rhs)
{
  return lhs.nodeid == rhs.nodeid;
}

现在你可以在node vector:

上调用带整数类型的std :: find
std::vector<node>::iterator position = std::find(cNode.begin(),cNode.end(), id);

等于:

std::vector<node>::iterator position = std::find(cNode.begin(),cNode.end(), node(id)); 

使用C ++ 11,您可以使用std :: find_if编写lambda作为替代方法:

auto pos = std::find_if(cNode.begin(), cNode.end(), 
           [id](const node& n){ return n.nodeid == id; } );

答案 2 :(得分:0)

nNode是一个向量,std::find搜索的值不是键。使用类似的东西 std::map<int,node>找到您的节点。

int id = 0;

typedef std::map<int,node> NodeMap;
NodeMap cNode;

NodeMap::iterator position = cNode.find(id);

如果您正在进行大量插入/删除操作,并保持对事物进行排序,请选择适当的容器,如地图或集合。

这基本上是C++ How to speed up my prog design

如果您将节点更改为:

struct node {
    vector<fingerTable> fTable;
    vector<string> data;
};

并从矢量更改为地图

map<int,node> cNode;

然后你的addPeer真的只这样做:

void chord::addPeer(int id)
{
    std::map<int, node>::iterator 
    pos = cNode.insert( std::make_pair(id, node() ) ).first;;

    if( pos != cNode.end() )
    {
        ++pos;
        vector<string> data = pos->second.data;
        pos->second.data.clear();
        dataShift( data, fIndex-1 );
    }
}//end addPeer

唯一剩下的问题是dataShift做了什么,是否需要索引?