从std :: vector查找std :: map中的对象

时间:2013-01-11 09:08:31

标签: c++ stdvector stdmap

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

但我不知道如何做这个比较...

抱歉新手问题。

7 个答案:

答案 0 :(得分:2)

std :: map经过优化,可以按键快速查找(在本例中为int值),不能快速按值查找(对象*)。因此,您唯一的选择是迭代整个地图,直到找到它为止。当地图很小并且代码部分对性能不重要时,您可以这样做。当性能很重要时,你可以添加一个额外的std :: set并存储当前被拖动的所有对象,或者你可以使对象本身知道它们当前是否被拖动,并将isDragged()方法添加到你的对象类。

答案 1 :(得分:0)

您可以更改方法并迭代拖动对象的地图,在每个拖动的对象上完成所需的工作,然后将对象添加到临时std::vector<object*>。循环结束后,您可以浏览向量,只对不在临时向量中的元素执行某些操作。

答案 2 :(得分:0)

我相信您可以使用set_difference。您必须实现自定义比较器,并且还必须在向量中对元素进行排序。除非你这样做,否则我认为你不能比为向量中的每个元素执行查找更好,以验证它是否存在于地图中。

答案 3 :(得分:0)

如果可能,使用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);

答案 4 :(得分:0)

您可以使用的一种方法是使用列表替换向量,并使此列表仅包含未标记的对象。

然后你会遍历这个列表。如果您想要所有对象,则可以遍历ilst和地图。不确定顺序的重要性,但是如果对象的id很重要(你存储在地图中),你可以根据地图中的id迭代“合并”通过列表和地图。

在这种情况下,原因列表优于向量,如果您将对象拖出集合的中间,那么从列表中删除是恒定时间。

答案 5 :(得分:0)

由于您说对象ID是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编译器。

答案 6 :(得分:0)

int来自哪里用于索引 地图?如果它是从object中提取的标识符,那么全部 你要做的就是在你的循环中提取它,看看它是否是 出现在地图中(使用map::find)。否则,你会 或者需要一个额外的地图,用对象*索引,或者你需要 需要遍历所有dragged_objects,看着 每一个,看它是否有你想要的地址(std::find_if)。 根据{{​​1}}的数量,这可能是 慢;但通常情况下,我猜是dragged_objects也是 空或只有一个条目。如果是这样的话,那就是 每次通过你的循环线性搜索是完美的 可以接受的。