代码之家  ›  专栏  ›  技术社区  ›  Navaneeth K N

在使用std::map时,这些实践是适当的吗?

  •  9
  • Navaneeth K N  · 技术社区  · 16 年前

    我有一些关于使用的问题 std::map :

    1. 正在使用 enum 作为关键 STD::地图 一个好的实践?请考虑以下代码:

      enum Shape{
          Circle,
          Rectangle
      };
      
      int main(int argc, char* argv[])
      {
           std::map<Shape,std::string> strMap;
           // strMap.insert(Shape::Circle,"Circle"); // This will not compile
           strMap[Shape::Circle] = "Circle";         // But this will work
           return 0;
      }
      
    2. 在上面的示例中,为什么调用 insert() 在重载时生成编译器错误 [] 操作员工作正常?建议使用以下哪种方法将项插入到 STD::地图 ?

    3. 我明白当 find() 方法用于 STD::地图 类,它不是在容器中执行顺序搜索,而是执行一些比顺序搜索快得多的对数搜索。这种理解正确吗?

    5 回复  |  直到 11 年前
        1
  •  12
  •   Craig M. Brandenburg Martin    11 年前
    1. 把枚举作为键类型本身并不坏。( 编辑 )但如果只使用顺序枚举值,则 std::vector 有了O(1)访问就更好了。
    2. insert 必须这样使用: mapVar.insert(make_pair(key, value)); 也见 cppreference.com .
    3. 对, std::map 有O(log(n))查找,如标准所保证的那样,如果n足够高,这比O(n)查找快。
        2
  •  5
  •   Alan    16 年前

    插入失败,因为值“类型”为std::pair

        3
  •  3
  •   community wiki 2 revs Aaron    16 年前

    1)将枚举作为std::map中的键是否是一个好的实践?

    好吧,为了提高效率,对于这样一个小的枚举,您最好使用向量或由值(如果您的值类型支持“空”值)或智能指针组成的tr1::数组。前任: vector<string>

    为了正确——我相信你没事。map可以与任何可排序的键类型(即具有operator<)一起工作,或者为其提供排序函数。默认情况下枚举具有排序

    2)在 strMap.insert(Shape::Circle,"Circle") 为什么insert方法[给出]编译器错误?

    因为insert不接受两个值。它需要一对。尝试:

    #include <utility>
    ...
    strMap.insert(make_pair(Circle, string("Circle")));
    

    3)当在map类中使用find()方法时,[它]执行一些对数搜索…对的?

    对。map::find是o(lg(map::size())时间。映射将其键值对存储在按键排序的数据结构中。插入和擦除是O(lg(n)),如图所示。它还提供双向迭代器,这意味着您可以在O(1)常量时间内找到映射中的下一个或上一个项,但不能一次向前和向后跳过多个元素。

    编辑: 已更正默认枚举具有排序。

        4
  •  1
  •   mmmmmmmm    16 年前

    试用使用

    strMap.insert(std::pair<Shape, std::string>(Circle,"Circle"));
    

    相反(不是shape::circle!).

    枚举值在与EnUM在C++中相同的范围内是可见的(非常丑陋,我绝对不喜欢它,但它就是这样!)

        5
  •  0
  •   Salman A    16 年前

    对于这样的情况,通常只需要将枚举静态映射到字符串,这样做通常更容易:

    enum Shape{
        Circle,
        Rectangle,
        NShapes,
    };
    
    char *ShapeNames[] = 
    {  
        "Circle",
        "Rectangle",    
    };
    
    void CheckShapeNames()
    {
        // Use a static_assert here instead if you have it in your library
        int ShapeNamesCount[(sizeof(ShapeNames)/sizeof(char*)) == NShapes];
    }
    

    从那时起,访问形状名称很简单,只需访问形状名称数组即可:

    string name = ShapeNames[Shape::Circle];
    

    甚至:

    for (int i=0; i < Shape::NShapes; ++i)
    {
        cout << ShapeNames[i];
    }