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

Comparing two vectors in the most effective way

本文关键字:两个 向量 比较 有效 方式      更新时间:2023-10-16

基本上我正在尝试记录应用程序的动画。我是通过逐帧记录来做到这一点的。

所以我要做的是记录一帧(动画的所有元数据)并将其与前一帧进行比较。如果任何对象不在上一帧中,那么我会保存它们并用它们做一些我不想让你们知道的事情: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

如您所见,如果一个新元素入到第二个列表中,那么之后的所有元素都将无序。我似乎找不到一种方法来解决这个问题,同时尽可能减少计算时间。任何帮助将不胜感激。

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

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

3) 使用二叉搜索来检查向量 1 中是否存在来自 vector2 的元素。

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

在下面的程序中,复制和移动构造函数以及赋值运算符被删除,以确保我们不会复制或移动大型对象。每帧仅在指针上执行一次排序,并且应该需要最少的时间。

#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 framen";
    objects.emplace('a');
    objects.emplace('b');
    objects.emplace('c');
    calculate_frame(objects);
    std::cout << "Start of framen";
    objects.emplace('d');
    objects.emplace('e');
    objects.emplace('f');
    calculate_frame(objects);
    std::cout << "Start of framen";
    objects.erase('a');
    objects.erase('c');
    calculate_frame(objects);
    std::cout << "Start of framen";
    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