以最有效的方式比较两个向量

时间:2016-04-26 19:11:43

标签: c++

基本上我正在尝试记录应用程序的动画。我是逐帧录制的。

所以我做的是记录一个帧(动画的所有元数据)并将其与前一帧进行比较。如果任何一个对象不在前一帧中,那么我保存它们并用它们做一些我不希望你们知道的东西:P

现在的问题是时间效率。我想能够在半秒内完成这个功能,因为它必须在半秒后再次调用。帧的大小将在1000-1500左右。

我检查了set_difference和其他方法,我认为这对我来说不够,因为,首先我有元数据无法排序我必须进行大量更改,即使我包含了排序标准,排序2个向量然后比较它们在计算上是昂贵的。

现在我提出的最好的是;

只是一个例子而不是我的真实代码

auto itr1 = list1.begin();
auto itr2 = list2.begin();

for (i; i<total_items;i++)
{
    if (*itr1 != *itr2)
        do something
        itr1++; itr2++;
    }
}

这是我想出的最好的,它的复杂性是n。现在,如果两个列表具有相同的大小,它就可以工作。但是如果最新列表的大小增加,那么所有元素都会出现故障,例如

a    a

b    b

c    c

d    z

e    d

f    e

g    f

正如您所看到的,如果在第二个列表中插入了新元素,那么之后的所有元素都将出现故障。我似乎无法找到解决这个问题的方法,同时尽量减少计算时间。 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

1)在大多数情况下,由于处理器的缓存使用率,std::vectorstd::list快。

2)对两个数组进行排序。将新元素插入到正确的位置 保持排序顺序。

3)使用二分搜索来检查vector1中vector2的元素是否存在。

复杂度应为M * log(N),其中N是第一个向量的长度,M是第二个向量的长度。

答案 1 :(得分:0)

在以下程序中,将删除复制和移动构造函数和赋值运算符,以确保不复制或移动大对象。每帧只对指针进行一次排序,并且需要的时间最短。

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <iterator>

class MyBigObject {
public:
    MyBigObject(char name) : name{name} {};
    MyBigObject(const MyBigObject&) = delete;
    MyBigObject(MyBigObject&&) = delete;
    MyBigObject& operator=(const MyBigObject&) = delete;
    MyBigObject& operator=(MyBigObject&&) = delete;

    bool operator< (const MyBigObject& rhs) const
    {
        return name < rhs.name;
    }

    char name;
    char bigdata[100000];
};

void doSomething(const MyBigObject& object)
{
    std::cout << "Working on object that was added:" << object.name << '\n';
}


void calculate_frame(const std::set<MyBigObject>& objects)
{
    static std::vector<const MyBigObject*> last_frame_objects;
    std::vector<const MyBigObject*> new_frame_objects;
    std::vector<const MyBigObject*> difference;
    std::for_each(objects.begin(),objects.end(),[&new_frame_objects](const MyBigObject& object) {new_frame_objects.push_back(&object); });
    std::sort(new_frame_objects.begin(),new_frame_objects.end());
    std::set_difference(new_frame_objects.begin(),new_frame_objects.end(),last_frame_objects.begin(),last_frame_objects.end(),
        std::inserter(difference,difference.begin()));
    for (auto object_ptr : difference) {
        doSomething(*object_ptr);
    }
    last_frame_objects = new_frame_objects;
}

int main()
{
    std::set<MyBigObject> objects;
    std::cout << "Start of frame\n";
    objects.emplace('a');
    objects.emplace('b');
    objects.emplace('c');
    calculate_frame(objects);
    std::cout << "Start of frame\n";
    objects.emplace('d');
    objects.emplace('e');
    objects.emplace('f');
    calculate_frame(objects);
    std::cout << "Start of frame\n";
    objects.erase('a');
    objects.erase('c');
    calculate_frame(objects);
    std::cout << "Start of frame\n";
    objects.emplace('c');
    calculate_frame(objects);
    return 0;
}

产地:

Start of frame
Working on object that was added:a
Working on object that was added:b
Working on object that was added:c
Start of frame
Working on object that was added:d
Working on object that was added:e
Working on object that was added:f
Start of frame
Start of frame
Working on object that was added:c