这是我的迭代器位置代码
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’
答案 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::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
做了什么,是否需要索引?