建议一个合适的算法来合并包含类对象的两个数组(不重复)
Suggest a suitable algorithm for merging two arrays containing class objects (without duplication)
我有一个数组,其中每个位置都包含一个具有三个int值(x,y,z)的类对象。现在,所有元素都必须从不同的数组复制到源数组中。对于每个数组元素,我们需要检查x、y、z值,以避免重复。有可能比o(n^2)更有效率吗?
如果您不介意丢失两个数组的原始顺序:
std::sort(first_array, first_array + N);
std::sort(second_array, second_array + M);
std::set_union(
first_array, first_array+N,
second_array, second_array+M,
target_array
);
CCD_ 1和CCD_。您需要为类定义operator<
或专门化std::less
:或者编写一个比较器函数并将其提供给sort
和set_union
。
时间复杂度是O(N log N + M log M)
——sort
是较慢的部分,然后set_union
是线性的。
如果N
0或second_array
本身可能已经包含重复数据(而不仅仅是它们之间),那么您需要额外的步骤来删除它们,这不仅会丢失顺序,还会丢失源阵列中的重复数据:
std::sort(first_array, first_array + N);
MyClass *first_end = std::unique(first_array, first_array + N);
std::sort(second_array, second_array + M);
MyClass *second_end = std::unique(second_array, second_array + M);
std::set_union(
first_array, first_end,
second_array, second_end,
target_array
);
或者,您可以编写set_union
的修改版本,在一次通过中进行合并和重复数据消除
[编辑:对不起,在写这篇文章时,我错过了结果最终会返回到first_array
,而不是单独的target_array
。set_union
不能将输出作为输入之一,因此这也需要目标阵列的额外内存,然后可以将其复制回源阵列,当然前提是源足够大。]
如果你确实想保留原始数组的顺序,那么你可以创建一个容器并边走边检查:
container<MyClass> items(first_array, first_array + N);
MyClass *dst = first_array + N;
for (MyClass *it = second_array; it != second_array + M; ++it) {
if (items.count(*it) == 0) {
items.insert(*it);
*dst++ = *it;
}
}
如果数组本身可以包含重复数据,则从items
为空和dst = first_array
开始,然后在两个输入数组上循环。
container
可以是std::set
(在这种情况下,时间是M
0,实际上又是O(N log N + M log M)
,您仍然需要一个顺序比较器),也可以是C++11中的std::unordered_set
(在这种情形下,预期时间是病理最坏情况下的O(N + M)
,您需要专门化std::hash
,或者编写一个散列函数,还提供一个等于函数,而不是顺序比较器)。在C++11之前,标准中没有其他哈希容器。
如果你不介意额外的内存和,也不介意丢失原始订单:
container<MyClass> items(first_array, first_array + N);
items.insert(second_array, second_array + M);
std::copy(items.begin(), items.end(), first_array);
如果你不想使用(太多)额外的内存,并且在源数组中有M个额外元素的空间,而不是只为结果留出空间:
std::copy(second_array, second_array + M, first_array + N);
std::sort(first_array, first_array + N + M);
MyClass *dst = std::unique(first_array, first_array + N + M);
// result now has (dst - first_array) elements
使用x、y、z定义对象的比较,对两个数组进行排序(如有必要,可以进行复制),然后创建一个辅助目标列表,将第一个数组中的所有元素复制到该列表中,并仅将第二个数组中不匹配的元素复制到其中。如有必要,请复制回第一个数组。
复杂性:max(O(n log n),O(m log m)),因为排序占主导地位,并且填充目的地列表是在O(max(n,m))上。
这并不是说该算法一定有效:对于较小的数组,复制和排序将占主导地位。
- 如何返回一个类的两个对象相加的结果
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 我有两个类需要在同一 cpp 文件中相互引用,但第一个类无法识别第二个类类型的对象
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 如何从文件中读取两个字符串和数字数组,并将它们存储在对象向量中
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- 通过插槽和信号在不同线程中的两个qt对象之间进行通信
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 如何在Qt中连接来自不同窗口的两个对象?
- 是否可以使用非常量指针调用非常量函数,以及当两个unique_ptrs指向同一个对象时程序的行为方式?
- C++两个对象,其中包含指向同一数组不同部分的指针
- 为什么将两个对象分配给另一个对象后,两个对象不一样?
- 绘制一个对象,比较模具缓冲区的两个不同值
- C++控制台应用,其中有两个冲突的对象不工作
- C++ 如何将两个 makefile 对象目标规则(位于另一个文件夹中)合并到一个目标/规则中?
- 当两个 std::map 对象相同时
- C++:在另外两个对象之间共享一个对象
- 为什么这两个卡片对象不等同?