简体   繁体   English

在这种情况下哪个更有效:std :: vector <bool> 或std :: unordered_map <int> ?

[英]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甚至intvector的不同实例化将消耗更多可修改的内存,但是由于更有效的代码(无位纠错)而可能会更有效。

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.

相关问题 在std :: unordered_map上进行迭代 <int, std::vector<Element> &gt; - Iterator over std::unordered_map<int, std::vector<Element>> 使用带预分配 std::unordered_map 的嵌套向量快速构造 unordered_map <int, vector<thing *> >?</int,> - Fast construction of unordered_map with nested vector with preallocation std::unordered_map<int, vector<Thing *>>? unordered_map 中的段错误<int, std::vector<double> &gt; - Seg fault in unordered_map <int, std::vector<double>> 如何在std :: unordered_map中更新向量 <std::string, std::vector<int> &gt;没有复制? - How to update the vectors in a std::unordered_map<std::string, std::vector<int>> without copying? std :: vector或std :: list for std :: unordered_map存储桶? - std::vector or std::list for std::unordered_map buckets? 对std :: unordered_map进行Boost :: serialization <double, std::vector<double> &gt; - Boost::serialization of an std::unordered_map<double, std::vector<double>> 将std :: unordered_map值移动到std :: vector - Moving an std::unordered_map values to std::vector 散列std :: unordered_map中使用的std :: array - Hash an std::array which used in std::unordered_map 更有效的结构为unordered_map <pair<int, int> ,int&gt; - more efficient structure as unordered_map<pair<int, int>, int> flann / util / serialization.h类std :: unordered_map <unsigned int, std::vector<unsigned int> &gt;&#39;没有名为&#39;serialize&#39;的成员 - flann/util/serialization.h class std::unordered_map<unsigned int, std::vector<unsigned int> >' has no member named 'serialize'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM