0

这是我的迭代器位置代码

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”找到我的向量索引

我知道 map 对我的情况来说是一个很好的 std 容器,但是我有点没时间做更改了,所以我必须坚持使用 vector ..

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’
4

3 回答 3

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 找到我们感兴趣的元素,而无需创建临时节点来搜索。

于 2013-02-17T08:44:16.983 回答
0

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

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现在您可以在向量上使用整数类型调用 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; } );
于 2013-02-17T08:43:18.713 回答
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);

如果您正在执行大量插入/删除操作,并保持排序,请选择适当的容器,例如 map 或 set。

这基本上是C++ 如何再次加快我的 prog 设计

如果您将节点更改为:

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,它是否需要索引?

于 2013-02-17T08:49:19.243 回答