我们使用的第三方库本质上是一个地图/字典。它没有提供任何相互测试两个对象的方法,我们需要这个。
更具体地说,两张地图S1&如果出现以下情况,则认为S2相同:
请注意,每张地图中的内部排序无关紧要,可能无法依赖,因此无法直接比较内部结构/成员。我们有办法比较键和值的相等性。
执行此操作的最佳算法是什么? Pseudo C ++很好,因为set类上的确切API足够接近我可以翻译的std :: map。
答案 0 :(得分:8)
比较尺寸
如果尺寸相等
迭代第一组中的键和每个键:
检查第二组
检查密钥的元素是否相等
如果至少有一个元素不相等,则第一个集合中的一个键在第二个集合中不存在或者大小不相等,则集合不相等。
答案 1 :(得分:0)
只要正确知道集合中存储的最大值,此方法就有效。取一个maximum value+1
大小的数组并将其初始化为0
。然后通过相应的increment
遍历第一组和'{1}}'key'位置的数组值。
现在通过value
遍历第二个集合并decrement
索引key
中数组中的值。
最后检查所有数组值是否为value
。如果没有,那么它们是zero
,否则它们是unequal
。
时间复杂度:equal
内存:O(N)
答案 2 :(得分:0)
假设您的map API有迭代器(或索引),有序,不包含重复项,并且还将其键和映射类型存储为嵌套typedef,您可以在std::map::operator==
中实现O(N)
的相同语义时间:
#include <functional> // less
#include <algorithm> // includes
// O(N) complexity
template<class MyMap, class KeyCmp = std::less<typename MyMap::key_type, class TCmp = std::equal<typename MyMap::mapped_type> >
bool set_equality(MyMap const& lhs, MyMap const& rhs, KeyCmp keycmp, TCmp tcmp)
{
typedef typename MyMap::value_type Pair;
return
lhs.size() == rhs.size() &&
std::includes(
lhs.begin(), lhs.end(),
rhs.begin(), rhs.end(),
[](Pair const& p1, Pair const& p2){
return keycmp(p1.first, p2.first) && tcmp(p1.second, p2.second);
})
;
}
答案 3 :(得分:0)
我认为要回答的一个主要问题是该字典结构中单个查找的成本是多少。如果您有例如一个hashmap的O(1),一个比较循环,就像utnapistim所暗示的那样,O(n)* O(1)= O(n)的复杂性。如果基础字典是std :: map,那么你将进行O(log n)查找,使其整体为O(n * log n)。如果您的dict是在未排序的数组或列表之上实现的,那么您将进行O(n)查找,使其整体为O(n ^ 2)。
我提到这些的原因是你也可以对两个词典进行排序并比较结果。对它们进行排序是O(n * log n),就像std :: map一样,所以在不知道查找复杂性的情况下,你无法决定是否对序列进行排序的成本更高或更低。
还有一个方面我想提一下,那就是字典的排序。你说你不能在那里做任何事情但是我只知道一个共同的结构并不能保证等内容意味着相等的顺序,一个未排序的数组或链表。但是,由于查找是O(n),因此作为字典表现不佳,所以有人选择它作为底层容器是不太可能的。写这个,我想知道如果hashmaps有不同的桶大小和可能的历史,是否给出了保证,我真的不确定。我敢肯定的是,最好的算法取决于字典的查找复杂性,所以我会尝试找到更多关于此的信息。即使测量也不会知道什么。一个记录良好的hack依赖于某种特定的性能行为是恕我直言。