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 個のオブジェクトを取得しました。たとえば、ノード ID "80" のインデックス/要素/位置を見つけようとしています。オブジェクトはすべてノード ID の昇順で並べ替えられていると仮定しています。

私の懸念は速度とメモリ使用量です。以前は使用していました

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 はコンテナ内の値を見つける方法しか記述していないため、コンパイラはこれを理解していません。それ以外の場合はどうすればよいでしょうか。2 つの int を含むオブジェクトがある場合、どちらを比較しますか?

の使用は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 はベクター型ですが、id(int 型) を渡します。オブジェクトに変換するにnodeは、暗黙の変換関数が必要です。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 を使用してラムダを記述することができます。

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);

多くの挿入/削除を行っていて、並べ替えを維持している場合は、マップやセットなどの適切なコンテナーを選択してください。

これは基本的にC++ であり、プログラムの設計を再び高速化する方法です。

ノードを次のように変更した場合:

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 に答える