[英]Which is more efficient in this scenario: std::vector<bool> or std::unordered_map<int>?
I know a classic programming interview question is " Given an array of N-1 integers which are numbers 1 through N with one of them missing, find the missing number ." 我知道一个经典的编程面试问题是“ 给定N-1个整数数组,它们是从1到N的数字,其中一个丢失了,找到丢失的数字 。” I'm thinking that
我在想
int missing_number ( int * arr, int n )
{
std::vector<bool> booVec(n, false);
int * offArrEnd = arr + n;
while (arr != offArrEnd) booVec[*arr++] = true;
return std::find_first_of(booVec.begin(), booVec.end(), false)
- booVec.begin() + 1;
}
would be a good solution since instantiating a vector<bool>
element to all false
will take a short amount of time, and so will modifying its elements via booVec[*arr++]
. 将
vector<bool>
元素实例化为false
会花费很短的时间,因此可以通过booVec[*arr++]
修改其元素,这将是一个很好的解决方案。 I know I could save 1 operation by changing it to 我知道我可以通过将其更改为1来保存操作
int missing_number ( int * arr, int n )
{
std::vector<bool> booVec(n, false);
int * offArrEnd = arr + n;
while (arr != offArrEnd) booVec[*arr++] = true;
std::vector<bool>::iterator offBooEnd = booVec.end();
return std::find_first_of(booVec.begin(), offBooEnd, false)
- offBooEnd + 1;
}
But I'm wondering if using a similar procedure with unordered_map
might be faster overall? 但是我想知道是否对
unordered_map
使用类似的过程是否整体上会更快? I presume it would take longer to instantiate every member of an unordered_map
, but it might take faster to modify its elements. 我认为实例化
unordered_map
每个成员将花费更长的时间,但是修改其元素可能会更快。
The technique you used above is the basis of Pigeonhole-Sort , with an additional guarantee of no duplicates making it even more efficient. 您上面使用的技术是Pigeonhole-Sort的基础,另外还保证了没有重复项,从而使效率更高。
Thus, the algorithm is O(n) (tight bound). 因此,该算法为O(n)(紧密边界)。
A std::unordered_set
has O(1) expected and O(n) worst case complexity for each of the N-1 insertions though, for a total of O(n) expected and O(n*n) worst case. 但是,对于每个N-1插入,
std::unordered_set
期望复杂度为O(1),最坏情况复杂度为O(n),对于期望的O(n)和最坏情况总计O(n * n)。
Even though the complexity in the expected (and best) case is equal, std::unordered_set
is a far more complex container and thus looses the race in any case. 即使预期(和最佳)情况下的复杂性相等,
std::unordered_set
还是一个更为复杂的容器,因此无论如何都失去了竞争。
std::vector<bool>
does not contain any bool
, but is a specialization using proxies to save space (Widely regarded as a design-failure)! std::vector<bool>
不包含任何bool
,而是一种使用代理来节省空间的专业化方法(被视为设计失败)!
Thus, using a different instantiation of vector
, with char
or even int
will consume more modifiable memory, but might due to more efficient code (no bit-twiddling) be more efficient. 因此,使用带有
char
甚至int
的vector
的不同实例化将消耗更多可修改的内存,但是由于更有效的代码(无位纠错)而可能会更有效。
Anyway, both implementations efficiency is dwarfed by simply adding the elements and subtracting the sum from what it would be for an uninterrupted sequence, like Nikola Dimitroff comments . 无论如何,通过简单地添加元素并从不中断序列的总和中减去总和,这两种实现方式的效率都 相形见 like ,例如Nikola Dimitroff的注释 。
int missing_number ( int * arr, int n )
{
unsigned long long r = (unsigned long long)n * (n+1) / 2;
for(n--)
r -= arr[n];
return (int)r;
}
vector
in this case where n
is bounded should be able to beat unordered_map
. 在这种情况下,
n
为界的vector
应该能够击败unordered_map
。 The underlying data structure for unordered_map
is essentially a vector
, where a hash is taken, and the modulus of the hash is taken to choose the index to start at in the vector
. unordered_map
的基础数据结构本质上是一个vector
,在该vector
中使用哈希,并使用哈希的模数来选择从vector
开始的索引。 (The vector
stores the hash table "buckets") As a result, a plain vector
is already a perfect hash table and you have a perfect hash -- N from the array! (
vector
存储哈希表“ buckets”)结果是,简单vector
已经是一个完美的哈希表,并且您拥有一个完美的哈希-数组中的N! Therefore, the extra mechanism provided by unordered_map
is going to be overhead you're not using. 因此,
unordered_map
提供的额外机制将成为您不使用的开销。
(And that's assuming you don't happen to fall into the case where unordered_map
can have O(n) lookup complexity due to hash collisions) (这是假设您不会碰到由于哈希冲突而导致
unordered_map
查找复杂度为O(n)的情况)
That said, vector<char>
may beat vector<bool>
due to the bitfield behavior of vector<bool>
. 就是说,由于
vector<bool>
的位域行为, vector<char>
可能会击败vector<bool>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.