0

C ++エキスパートへの簡単な質問:

私が取り組んでいるプロジェクトには、ベクター内のオブジェクトへのポインターを含むクラスがあります。

    std::vector<object*> objects;

オブジェクトにオフセットを追加する構造体があります(Point2Dは明らかにx、y座標です)

    struct DraggedObject{
    object* obj;
    Point2D offset;

    DraggedObject():obj(NULL),offset(Point2D(0,0)){}
};

また、オブジェクトをドラッグすると、次のようなstd::mapに追加されます。

    std::map <int, DraggedObject> dragged_objects;

だから私の問題はこれです:このオブジェクトを移動する必要があるループがありますが、ドラッグされたオブジェクトはスキップします。私の質問は、オブジェクトベクトルをループして、オブジェクトがdragged_objectマップ上にあるかどうかを確認する方法はありますか?

私はこのようなことをしています:

for(std::vector<object*>::iterator it = objects.begin(); it != objects.end(); it++){
    if(//Object is not in dragged_objects){
        (*it)->move_to( Point2D( //Some point);
    }else{
        (*it)->move_to (Point2D (//Point of dragged object);
}

しかし、私はこの比較を行う方法がわかりません...

初心者の質問でごめんなさい。

4

7 に答える 7

2

std::map は、値 (オブジェクト*) による高速ルックアップではなく、キー (この場合は int 値) による高速ルックアップ用に最適化されています。したがって、唯一の賭けは、マップが見つかるまでマップ全体を反復することです。マップが小さく、コード セクションのパフォーマンスが重要でない場合は、それを行うことができます。パフォーマンスが重要な場合は、追加の std::set を追加して、現在ドラッグされているすべてのオブジェクトをその中に格納するか、現在ドラッグされているかどうかをオブジェクト自体に認識させ、 isDragged() メソッドをオブジェクトクラス。

于 2013-01-11T09:15:58.190 に答える
0

使用できるアプローチの 1 つは、ベクトルをリストに置き換えて、このリストにドラッグされていないオブジェクトのみを含めることです。

次に、このリストを反復処理します。すべてのオブジェクトが必要な場合は、ilst とマップの両方を反復処理します。それを行うための順序がどれほど重要かはわかりませんが、オブジェクトのIDが重要な場合(マップに保存する場合)、マップ内のIDに基づいて、リストとマップを「マージ」することができます。

この場合、ベクトルよりもリストの方が適している理由は、コレクションの途中からオブジェクトをドラッグしている場合で、リストからの削除に一定の時間がかかる場合です。

于 2013-01-11T09:28:44.970 に答える
0

オブジェクト ID は map のキーだとおっしゃっていたので、 map のメソッドをdragged_objects使用できますfind。私はそれがこのようになるべきだと信じています。

std::map::iterator miter;
for (auto &obj : objects)
{
    miter = dragged_objects.find(obj.id);
    if (miter != dragged_objects.end()) {
        /* do for non-dragged objects */
    } else {
        /* do for dragged objects */
    }
}

必要に応じて、C++11 以外のコンパイラに合わせて調整します。

于 2013-01-11T09:34:31.380 に答える
0

intマップへのインデックス付けに使用される which はどこから来たのですか? から抽出された識別子である場合objectは、ループで抽出し、マップに存在するかどうかを確認するだけです ( を使用map::find)。それ以外の場合は、object* でインデックス付けされた追加のマップが必要になるか、すべての を繰り返し処理してdragged_objects、各マップに必要なアドレスがあるかどうかを確認する必要があります ( std::find_if)。の数によってはdragged_objects、これは遅くなる可能性があります。dragged_objectsしかし、通常、それは空であるか、単一のエントリしかないと思います。この場合、ループごとの線形検索は完全に受け入れられます。

于 2013-01-11T09:37:47.250 に答える
0

set_differenceを利用できると思います。カスタム コンパレータを実装する必要があり、また、ベクター内の要素を並べ替える必要があります。そうしない限り、ベクター内の各要素に対して検索を実行して、マップに存在するかどうかを確認するよりも良いことはないと思います。

于 2013-01-11T09:20:34.373 に答える
0

可能であれば、たとえばの代わりに、キーを使用して、ドラッグされたオブジェクトを container( map)に収集します。次に、次のように書くことができます。object*std::map <object*, DraggedObject>std::map <int, DraggedObject>if

 if(dragged_objects.count(*it)){
        (*it)->move_to( Point2D( //Some point);
    }else{
        (*it)->move_to (Point2D (//Point of dragged object);
于 2013-01-11T09:21:39.133 に答える
0

アプローチを変更して、ドラッグされたオブジェクトのマップを反復し、ドラッグされた各オブジェクトに対して必要な作業を行ってから、オブジェクトを一時的に追加することができますstd::vector<object*>。ループが終了したら、ベクターを調べて、一時ベクターにない要素に対してのみ何かを行うことができます。

于 2013-01-11T09:16:02.043 に答える