【问题标题】:How does a vector as a key works internally in C++?作为键的向量如何在 C++ 内部工作?
【发布时间】:2020-06-01 06:28:01
【问题描述】:

这个 SO 回答说 STL Map with a Vector for the Key 向量可以用作键。因此,当我们使用向量作为键时。这实际上是如何工作的,因为键需要是唯一的,所以当我们插入另一个具有相同元素的向量时,map 会逐个元素地检查重复的元素,或者向量的名称确实指定了什么?就像数组的名字代表基地址一样。因此,数组可以用作键,因为在这种情况下基地址可以用作键,但在向量的情况下,键是什么。它在内部是如何工作的。

因为当我打印向量的名称时,我确实得到了一个错误

vector<int> v;
cout<<v; //error

【问题讨论】:

  • 打印矢量名称是什么意思?
  • has operators == and &lt; 这有什么帮助?我的问题是检查重复元素将映射比较矢量关键元素的元素
  • @PulkitBhatnagar 但是...没有人会强迫您使用std::vector 作为std::map 的键。 你为你使用的东西付费。这是可以做到的,也许有一些用例,但你肯定可以改变你选择的数据结构。 STL 容器被设计为具有最大的通用性,并且可以以用户想要使用它们的任何方式使用。
  • @PulkitBhatnagar 例如,参见Why is std::map implemented as a red-black tree?
  • @PulkitBhatnagar 直接存储。 std::map 会将键和值复制到自身中。 std::unordered_map 可以存储密钥的哈希值。

标签: c++ arrays dictionary vector stl


【解决方案1】:

对象的名称和该对象的内容始终是不相关的东西。

operator == for std::vector 将首先比较向量的长度,然后使用 operator == 比较每个元素。

operator &lt; 按字典顺序比较向量中的元素,即它返回 x[i] &lt; y[i] 向量中的第一个不相等元素 xy

这些是std::map 对用作Key 的类型的要求。由于std::vector 满足两者,它可以被用作Key。请注意,由 vector 管理的类型还必须重载这些运算符才能使其工作(因为 std::vector 依赖于这些运算符来实现它自己的运算符)。

【讨论】:

    【解决方案2】:

    类模板 std::vector 有一个重载的运算符

    template <class T, 
    class Allocator>
    bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);
    

    基于标准算法std::lexicographical_compare

    这是一个演示程序。

    #include <iostream>
    #include <iomanip>
    #include <vector>
    #include <iterator>
    #include <algorithm>
    
    int main() 
    {
        std::vector<int> v1 = { 1, 2 };
        std::vector<int> v2 = { 1, 2, 3 };
        std::vector<int> v3 = { 2 };
    
        std::cout << std::boolalpha << ( v1 < v2 ) << '\n';
        std::cout << std::lexicographical_compare( std::begin( v1 ), std::end( v1 ),
                                                   std::begin( v2 ), std::end( v2 ) )
                 << '\n';                                              
    
        std::cout << std::boolalpha << ( v1 < v3 ) << '\n';
        std::cout << std::lexicographical_compare( std::begin( v1 ), std::end( v1 ),
                                                   std::begin( v3 ), std::end( v3 ) )
                 << '\n';                                              
    
        std::cout << std::boolalpha << ( v2 < v3 ) << '\n';
        std::cout << std::lexicographical_compare( std::begin( v2 ), std::end( v2 ),
                                                   std::begin( v3 ), std::end( v3 ) )
                 << '\n';                                              
    
        return 0;
    }
    

    它的输出是

    true
    true
    true
    true
    true
    true
    

    所以类可以作为map中的键。

    默认情况下,类模板映射使用函数对象 std::less ,而后者又使用运算符

    template <class Key, class T, class Compare = less<Key>,
    class Allocator = allocator<pair<const Key, T>>>
    class map 
    {
        //...
    };
    

    但是对于类模板 std::vector 没有重载运算符

    【讨论】:

    • 我最近在几乎所有关于 SO 的 C++ 问题中都看到了你的答案,我不知道在我的一生中我是否能够实现你所拥有的,但我会尽力而为。感谢您的回答
    猜你喜欢
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    相关资源
    最近更新 更多