2009-01-28 28 views
9

Tôi có một số câu hỏi về việc sử dụng std::map:Có phải những thực tiễn phù hợp này khi làm việc với std :: map?

  1. là sử dụng một enum là chìa khóa trong std::map một thực hành tốt? Xét đoạn mã sau:

    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. Trong ví dụ trên, tại sao các cuộc gọi đến insert() tạo ra một lỗi biên dịch trong khi quá tải [] điều hành hoạt động chính xác? Bạn nên sử dụng phương pháp nào trong số những phương pháp này để chèn các mục vào một số std::map?

  3. Tôi hiểu rằng khi phương pháp find() được sử dụng trên lớp std::map, nó không thực hiện tìm kiếm tuần tự trong vùng chứa mà thực hiện tìm kiếm lôgarit nhanh hơn tìm kiếm tuần tự. Sự hiểu biết này có đúng không?

Trả lời

12
  1. Có enum là key_type không phải là xấu của chính nó. (chỉnh sửa) Nhưng nếu bạn chỉ sử dụng các giá trị enum tuần tự, thì std::vector với quyền truy cập O (1) thậm chí còn tốt hơn.
  2. insert phải được sử dụng như sau: mapVar.insert(make_pair(key, value)); Xem thêm cppreference.com.
  3. Có, std::map có tra cứu O (log (n)), được đảm bảo theo tiêu chuẩn, và điều này nhanh hơn O (n) nếu n đủ cao.
+0

Đối với chỉnh sửa của bạn, tôi không nhìn thấy nó rất rõ ràng. Hãy tưởng tượng rằng các hình dạng phát triển đến bảy: Circle, Rectangle, Triangle, Egg, bất cứ điều gì. Sau đó, bạn có một mảnh lớp có biến "hình dạng" và muốn truy cập vào giá trị assotiated. Bản đồ sẽ nhanh hơn. –

+0

Để Daniel: Như cha mẹ đã đề cập, một bản đồ sẽ chậm hơn vì nó là O (logn) so với thời gian cố định của vectơ. –

+0

Có nhưng có thể tôi đang thiếu điều gì đó. Toàn bộ điểm trong bản đồ là bạn có một khóa và tìm kiếm giá trị được xác nhận _its_! Tôi biết Vòng tròn chính và muốn truy cập "Vòng kết nối" trong bản đồ, tôi không thể làm điều đó bằng véc tơ. Tôi có thể có một vector _of_ các phím và một số khác _of_ các giá trị, nhưng không tra cứu. –

3

1) Giữ một enum là chìa khóa trong tiêu chuẩn :: bản đồ là một thực hành tốt? Vâng, vì hiệu quả, với một enum nhỏ như vậy, bạn nên được tốt hơn off với một vector hoặc tr1 :: mảng của một trong hai giá trị (nếu loại giá trị của bạn hỗ trợ các giá trị 'trống') hoặc con trỏ thông minh. ví dụ: vector<string>

Để chính xác - Tôi tin rằng bạn ổn. Bản đồ có thể hoạt động với bất kỳ loại khóa nào có thể sắp xếp - tức là có toán tử < hoặc bạn cung cấp chức năng sắp xếp. Enums có đặt hàng theo mặc định

2) Trong strMap.insert(Shape::Circle,"Circle") tại sao phương thức chèn là [cho] lỗi trình biên dịch?

Do chèn không có hai giá trị. phải mất một cặp. thử:

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

3) Khi phương thức find() được sử dụng trong lớp bản đồ, [nó] đang thực hiện tìm kiếm lôgarit ... đúng không?

Có. map :: find is O (lg (bản đồ :: size())) thời gian. bản đồ lưu trữ các cặp khóa-giá trị của nó trong một cấu trúc dữ liệu được sắp xếp theo khóa. chèn và xóa là O (lg (n)), như là tìm. Nó cũng cung cấp các trình vòng lặp hai chiều, có nghĩa là bạn có thể tìm thấy mục tiếp theo hoặc trước đó trong bản đồ trong O (1) thời gian không đổi, nhưng bạn không thể bỏ qua và chuyển tiếp nhiều phần tử cùng một lúc.

Chỉnh sửa: sửa chữa các enums có đặt hàng theo mặc định.

+0

Vì enums là ints, bạn có thực sự cần phải cung cấp một thứ tự? Tôi không nghĩ vậy. –

+0

Bạn không thể có vectơ . Bạn có thể có một véc tơ và một véc tơ . Để tra cứu khóa-giá trị, bạn _need_ một bản đồ. –

+0

@Daniel - vector _is_ một cấu trúc dữ liệu liên kết. nó ánh xạ các số nguyên không dấu tuần tự đến các giá trị. enums là số nguyên không dấu, và được tuần tự theo mặc định. xem nhận xét về câu trả lời của gimpf. – Aaron

1

Hãy thử sử dụng

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

thay vì (không Shape :: Vòng!).

giá trị Enum có thể nhìn thấy ở phạm vi tương tự như enum là trong C++ (rất xấu xí và tôi hoàn toàn không thích nó, nhưng đó là cách nó được!)

5

Chèn thất bại vì value_type là std :: cặp

+0

tại sao điều này lại bị bỏ phiếu? loại giá trị cho bản đồ là std :: pair. Các bạn là những người trung thành! – Alan

+0

+1 để bù đắp phần ghi đè không cần thiết: P. –

0

Đối với những tình huống như thế này, nơi bạn thường chỉ muốn một ánh xạ tĩnh của enums đến chuỗi, nó thường dễ dàng hơn để làm điều gì đó như thế này:

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]; 
} 

Từ đó trở đi, truy cập vào tên hình dạng rất đơn giản là vấn đề truy cập mảng ShapeNames:

string name = ShapeNames[Shape::Circle]; 

hoặc thậm chí:

for (int i=0; i < Shape::NShapes; ++i) 
{ 
    cout << ShapeNames[i]; 
} 
Các vấn đề liên quan