任何人都可以解释一个无序集是如何工作的吗?我也不确定一套是如何工作的。我的主要问题是它的查找功能的效率如何。
例如,这个总的大O运行时间是多少?
vector<int> theFirst;
vector<int> theSecond;
vector<int> theMatch;
theFirst.push_back( -2147483648 );
theFirst.push_back(2);
theFirst.push_back(44);
theSecond.push_back(2);
theSecond.push_back( -2147483648 );
theSecond.push_back( 33 );
//1) Place the contents into a unordered set that is O(m).
//2) O(n) look up so thats O(m + n).
//3) Add them to third structure so that's O(t)
//4) All together it becomes O(m + n + t)
unordered_set<int> theUnorderedSet(theFirst.begin(), theFirst.end());
for(int i = 0; i < theSecond.size(); i++)
{
if(theUnorderedSet.find(theSecond[i]) != theUnorderedSet.end())
{
theMatch.push_back( theSecond[i] );
cout << theSecond[i];
}
}
答案 0 :(得分:4)
unordered_set
和所有其他unordered_
数据结构都使用哈希,如@Sean所述。散列涉及用于插入的摊销的恒定时间,并且接近于用于查找的恒定时间。哈希函数本质上需要一些信息并从中生成一个数字。在某种意义上,它是一个函数,相同的输入必须产生相同的输出。但是,不同的输入可能会导致相同的输出,从而导致所谓的碰撞。查找将保证是“完美哈希函数”的恒定时间,即没有冲突的查询。实际上,输入数字来自您存储在结构中的元素(比如它的值,它是基本类型)并将其映射到数据结构中的某个位置。因此,对于给定的键,该函数将您带到存储元素的位置,而不需要任何遍历或搜索(为简单起见忽略此处的冲突),因此需要恒定的时间。这些结构有不同的实现(开放寻址,链接等)。请参阅hash table,hash function。我还推荐Skiena的The Algorithm Design Manual第3.7节。现在,关于big-O复杂性,你是正确的,你有O(n)+ O(n)+ O(重叠的大小)。由于重叠不能大于m和n中的较小者,因此总体复杂度可以表示为O(kN),其中N在m和n之间最大。所以,O(N)。同样,这是“最佳情况”,没有碰撞,并且具有完美的散列效果。
set
和multi_set
使用二叉树,因此插入和查找通常为O(logN)。散列结构与二叉树的实际性能将取决于N,因此最好尝试这两种方法并在实际运行场景中对其进行分析。
答案 1 :(得分:2)
所有std :: unordered _ *()数据类型都使用哈希来执行查找。看看Boost关于这个主题的文档,我想你会很快得到一个理解。
http://www.boost.org/doc/libs/1_46_1/doc/html/unordered.html