Có bất kỳ lợi thế nào của việc sử dụng bản đồ trên unordered_map trong trường hợp các khóa tầm thường không?


371

Một cuộc nói chuyện gần đây về unordered_mapC ++ khiến tôi nhận ra rằng tôi nên sử dụng unordered_mapcho hầu hết các trường hợp tôi đã sử dụng maptrước đây, vì hiệu quả của việc tra cứu ( khấu hao O (1) so với O (log n) ). Hầu hết thời gian tôi sử dụng bản đồ, tôi sử dụng inthoặc std::stringlà loại khóa; do đó, tôi không gặp vấn đề gì với định nghĩa của hàm băm. Càng nghĩ về nó, tôi càng nhận ra rằng tôi không thể tìm thấy bất kỳ lý do nào của việc sử dụng std::mapmột std::unordered_maptrong các trường hợp khóa với các loại đơn giản - tôi đã xem qua các giao diện và không tìm thấy bất kỳ sự khác biệt đáng kể sẽ ảnh hưởng đến mã của tôi.

Do đó câu hỏi: liệu có bất kỳ lý do thực sự để sử dụng std::maptrên std::unordered_maptrong trường hợp của các loại đơn giản như intstd::string?

Tôi đang hỏi từ quan điểm lập trình nghiêm ngặt - Tôi biết rằng nó không được coi là hoàn toàn tiêu chuẩn và nó có thể gây ra vấn đề với việc chuyển.

Ngoài ra, tôi hy vọng rằng một trong những câu trả lời đúng có thể là "hiệu quả hơn đối với các tập dữ liệu nhỏ hơn" vì chi phí nhỏ hơn (có đúng không?) - do đó tôi muốn hạn chế câu hỏi trong trường hợp số lượng các khóa không tầm thường (> 1 024).

Chỉnh sửa: duh, tôi quên mất điều hiển nhiên (cảm ơn GMan!) - vâng, bản đồ được đặt hàng tất nhiên - tôi biết điều đó, và đang tìm kiếm những lý do khác.


22
Tôi thích đặt câu hỏi này trong các cuộc phỏng vấn: "Khi nào thì sắp xếp nhanh tốt hơn sắp xếp bong bóng?" Câu trả lời cho câu hỏi cung cấp cái nhìn sâu sắc về ứng dụng thực tế của lý thuyết phức tạp và không chỉ các tuyên bố trắng đen đơn giản như O (1) tốt hơn O (n) hay O (k) tương đương với O (logn), v.v. ..

42
@Beh, tôi nghĩ bạn có nghĩa là "khi nào thì sắp xếp bong bóng tốt hơn sắp xếp nhanh": P
Kornel Kisielewicz

2
Một con trỏ thông minh sẽ là một chìa khóa tầm thường?
thomthom

Đây là một trong những trường hợp trong đó bản đồ là lợi thế: stackoverflow.com/questions/51964419/
Kẻ

Câu trả lời:


399

Đừng quên rằng mapgiữ cho các yếu tố của nó được ra lệnh. Nếu bạn không thể từ bỏ điều đó, rõ ràng bạn không thể sử dụng unordered_map.

Một điều khác cần ghi nhớ là unordered_mapthường sử dụng nhiều bộ nhớ hơn. mapchỉ có một vài con trỏ giữ nhà và bộ nhớ cho mỗi đối tượng. Ngược lại, unordered_mapcó một mảng lớn (những thứ này có thể trở nên khá lớn trong một số triển khai), và sau đó thêm bộ nhớ cho từng đối tượng. Nếu bạn cần phải nhận thức bộ nhớ, mapnên chứng minh tốt hơn, bởi vì nó thiếu mảng lớn.

Vì vậy, nếu bạn cần tìm kiếm thuần túy, tôi muốn nói unordered_maplà cách để đi. Nhưng luôn có sự đánh đổi và nếu bạn không đủ khả năng thì bạn không thể sử dụng nó.

Chỉ từ kinh nghiệm cá nhân, tôi đã tìm thấy một sự cải thiện to lớn về hiệu suất (tất nhiên là được đo) khi sử dụng unordered_mapthay vì maptrong bảng tra cứu thực thể chính.

Mặt khác, tôi thấy nó chậm hơn nhiều khi liên tục chèn và loại bỏ các yếu tố. Thật tuyệt vời cho một bộ sưu tập các yếu tố tương đối tĩnh, nhưng nếu bạn đang thực hiện hàng tấn chèn và xóa thì băm + xô có vẻ như cộng lại. (Lưu ý, điều này đã qua nhiều lần lặp lại.)


3
Một điều nữa về thuộc tính khối bộ nhớ (r) lớn của unordered_map so với map (hoặc vector vs list), heap process mặc định (nói Windows ở đây) được tuần tự hóa. Phân bổ các khối (nhỏ) với số lượng lớn trong một ứng dụng đa luồng rất tốn kém.
ROAR

4
RA: Bạn có thể kiểm soát phần nào điều đó với loại phân bổ của riêng bạn kết hợp với bất kỳ vùng chứa nào, nếu bạn nghĩ nó quan trọng đối với bất kỳ chương trình cụ thể nào.

9
Nếu bạn biết kích thước của unordered_mapvà dự trữ khi bắt đầu - bạn vẫn phải trả tiền phạt cho nhiều lần chèn? Giả sử, bạn chỉ chèn một lần khi bạn tạo bảng tra cứu - và sau đó chỉ đọc từ đó.
thomthom

3
@thomthom Theo như tôi có thể nói, sẽ không có hình phạt nào về hiệu suất. Lý do hiệu suất gây ấn tượng là do thực tế là nếu mảng phát triển quá lớn, nó sẽ thực hiện lại tất cả các yếu tố. Nếu bạn gọi dự trữ, nó sẽ có khả năng thử lại các yếu tố hiện có nhưng nếu bạn gọi nó khi bắt đầu, thì sẽ không bị phạt, ít nhất là theo cplusplus.com/reference/unordered_map/unordered_map/reserve
Richard Fung

6
Tôi khá chắc chắn rằng trí nhớ khôn ngoan thì ngược lại. Giả sử hệ số tải 1.0 mặc định cho vùng chứa không có thứ tự: bạn có một con trỏ cho mỗi phần tử cho nhóm và một con trỏ cho mỗi phần tử cho nhóm phần tử tiếp theo, do đó, bạn kết thúc với hai con trỏ cộng với dữ liệu cho mỗi phần tử. Mặt khác, đối với một container được đặt hàng, việc triển khai cây RB điển hình sẽ có: ba con trỏ (trái / phải / cha mẹ) cộng với một bit màu do căn chỉnh sẽ tạo ra một từ. Đó là bốn con trỏ cộng với dữ liệu cho mỗi yếu tố.
Yakov Galka

126

Nếu bạn muốn so sánh tốc độ của việc triển khai std::mapstd::unordered_maptriển khai của mình , bạn có thể sử dụng dự án spzzyhash của Google có chương trình time_hash_map để tính thời gian cho chúng. Ví dụ: với gcc 4.4.2 trên hệ thống Linux x86_64

$ ./time_hash_map
TR1 UNORDERED_MAP (4 byte objects, 10000000 iterations):
map_grow              126.1 ns  (27427396 hashes, 40000000 copies)  290.9 MB
map_predict/grow       67.4 ns  (10000000 hashes, 40000000 copies)  232.8 MB
map_replace            22.3 ns  (37427396 hashes, 40000000 copies)
map_fetch              16.3 ns  (37427396 hashes, 40000000 copies)
map_fetch_empty         9.8 ns  (10000000 hashes,        0 copies)
map_remove             49.1 ns  (37427396 hashes, 40000000 copies)
map_toggle             86.1 ns  (20000000 hashes, 40000000 copies)

STANDARD MAP (4 byte objects, 10000000 iterations):
map_grow              225.3 ns  (       0 hashes, 20000000 copies)  462.4 MB
map_predict/grow      225.1 ns  (       0 hashes, 20000000 copies)  462.6 MB
map_replace           151.2 ns  (       0 hashes, 20000000 copies)
map_fetch             156.0 ns  (       0 hashes, 20000000 copies)
map_fetch_empty         1.4 ns  (       0 hashes,        0 copies)
map_remove            141.0 ns  (       0 hashes, 20000000 copies)
map_toggle             67.3 ns  (       0 hashes, 20000000 copies)

2
Có vẻ như bản đồ không có thứ tự đánh bại bản đồ trên hầu hết các hoạt động. Hãy kiểm tra khi chèn ...
Michael IV

7
spzzyhash không tồn tại nữa. nó đã bị xóa hoặc gỡ xuống
Người dùng9102d82

1
@ User9102d82 Tôi đã chỉnh sửa câu hỏi để tham khảo một liên kết waybackmachine .
andreee

Chỉ để đảm bảo rằng những người khác cũng chú ý đến các số khác ngoài thời gian: Những thử nghiệm đó được thực hiện với các đối tượng / cơ sở dữ liệu 4 byte hay còn gọi là int. Nếu bạn lưu trữ thứ gì đó yêu cầu băm nặng hơn hoặc lớn hơn (làm cho hoạt động sao chép nặng hơn), bản đồ tiêu chuẩn có thể nhanh chóng có lợi thế!
AlexGeorg

82

Tôi sẽ lặp lại cùng một điểm mà GMan đã thực hiện: tùy thuộc vào loại sử dụng, std::mapcó thể (và thường là) nhanh hơn std::tr1::unordered_map(sử dụng triển khai có trong VS 2008 SP1).

Có một vài yếu tố phức tạp cần ghi nhớ. Ví dụ: trong std::map, bạn đang so sánh các khóa, có nghĩa là bạn chỉ nhìn vào đủ điểm bắt đầu của một khóa để phân biệt giữa các nhánh con bên phải và bên trái của cây. Theo kinh nghiệm của tôi, gần như lần duy nhất bạn nhìn vào toàn bộ khóa là nếu bạn đang sử dụng một cái gì đó giống như int mà bạn có thể so sánh trong một hướng dẫn. Với một loại khóa điển hình hơn như std :: string, bạn thường chỉ so sánh một vài ký tự hoặc hơn.

Một hàm băm khá, ngược lại, luôn luôn nhìn vào toàn bộ khóa. IOW, ngay cả khi tra cứu bảng là độ phức tạp không đổi, bản thân hàm băm có độ phức tạp gần như tuyến tính (mặc dù trên độ dài của khóa, không phải số lượng mục). Với chuỗi dài như chìa khóa, một std::mapcó thể kết thúc một tìm kiếm trước khi unordered_mapthậm chí sẽ bắt đầu tìm kiếm của mình.

Thứ hai, trong khi có một số phương pháp thay đổi kích thước bảng băm, hầu hết chúng đều khá chậm - đến mức trừ khi việc tra cứu thường xuyên hơn đáng kể so với chèn và xóa, std :: map thường sẽ nhanh hơn std::unordered_map.

Tất nhiên, như tôi đã đề cập trong nhận xét về câu hỏi trước đây của bạn, bạn cũng có thể sử dụng bảng cây. Điều này có cả ưu điểm và nhược điểm. Một mặt, nó giới hạn trường hợp xấu nhất đối với cây. Nó cũng cho phép chèn và xóa nhanh, bởi vì (ít nhất là khi tôi đã thực hiện) Tôi đã sử dụng một kích thước bảng cố định. Loại bỏ tất cả thay đổi kích thước bảng cho phép bạn giữ bảng băm của mình đơn giản hơn nhiều và thường nhanh hơn.

Một điểm khác: các yêu cầu đối với bản đồ băm và dựa trên cây là khác nhau. Băm rõ ràng đòi hỏi một hàm băm và so sánh bằng, trong đó các bản đồ được yêu cầu yêu cầu so sánh ít hơn so với. Tất nhiên các hybrid tôi đã đề cập đòi hỏi cả hai. Tất nhiên, đối với trường hợp phổ biến sử dụng chuỗi làm khóa, đây thực sự không phải là vấn đề, nhưng một số loại khóa phù hợp với thứ tự tốt hơn so với băm (hoặc ngược lại).


2
Thay đổi kích thước băm có thể được giảm bớt bằng dynamic hashingkỹ thuật, bao gồm việc có một giai đoạn chuyển tiếp trong đó mỗi lần bạn chèn một mục, bạn cũng có thể làm lại kcác mục khác. Tất nhiên, điều đó có nghĩa là trong quá trình chuyển đổi, bạn phải tìm kiếm 2 bảng khác nhau ...
Matthieu M.

2
"Với các chuỗi dài làm khóa, một std :: map có thể kết thúc tìm kiếm trước khi unordered_map thậm chí sẽ bắt đầu tìm kiếm." - nếu khóa không có trong bộ sưu tập. Nếu nó có mặt thì tất nhiên độ dài cần phải được so sánh để xác nhận trận đấu. Nhưng tương tự như vậy unordered_mapcần phải xác nhận một kết quả khớp băm với một so sánh đầy đủ, vì vậy tất cả phụ thuộc vào phần nào của quá trình tra cứu mà bạn đang đối chiếu.
Steve Jessop

2
bạn thường có thể thay thế hàm băm dựa trên kiến ​​thức về dữ liệu. ví dụ: nếu chuỗi dài của bạn thay đổi nhiều hơn trong 20 byte cuối so với 100 đầu tiên, chỉ cần băm 20. cuối cùng
Erik Aronesty

56

Tôi bị thu hút bởi câu trả lời từ @Jerry Coffin, người cho rằng bản đồ được đặt hàng sẽ thể hiện hiệu suất tăng trên các chuỗi dài, sau một số thử nghiệm (có thể tải xuống từ pastebin ), tôi thấy rằng điều này dường như chỉ đúng với các bộ sưu tập của các chuỗi ngẫu nhiên, khi bản đồ được khởi tạo với một từ điển được sắp xếp (chứa các từ có số lượng tiền tố trùng lặp đáng kể), quy tắc này bị phá vỡ, có lẽ là do độ sâu của cây tăng lên cần thiết để lấy giá trị. Các kết quả được hiển thị bên dưới, cột số 1 là thời gian chèn, thứ 2 là thời gian tìm nạp.

g++ -g -O3 --std=c++0x   -c -o stdtests.o stdtests.cpp
g++ -o stdtests stdtests.o
gmurphy@interloper:HashTests$ ./stdtests
# 1st number column is insert time, 2nd is fetch time
 ** Integer Keys ** 
 unordered:      137      15
   ordered:      168      81
 ** Random String Keys ** 
 unordered:       55      50
   ordered:       33      31
 ** Real Words Keys ** 
 unordered:      278      76
   ordered:      516     298

2
Cảm ơn vì bài kiểm tra. Để đảm bảo chúng tôi không đo tiếng ồn, tôi đã thay đổi nó để thực hiện từng thao tác nhiều lần (và chèn bộ đếm thay vì 1 vào bản đồ). Tôi đã chạy nó qua một số khóa khác nhau (từ 2 đến 1000) và tối đa ~ 100 khóa trên bản đồ, std::mapthường vượt trội hơn std::unordered_map, đặc biệt là đối với các phím số nguyên nhưng ~ 100 phím có vẻ như mất cạnh và std::unordered_mapbắt đầu thắng. Chèn một chuỗi đã được đặt hàng vào một std::maprất tệ, bạn sẽ gặp trường hợp xấu nhất (O (N)).
Andreas Magnusson

30

Tôi sẽ chỉ ra rằng ... có nhiều loại unordered_maps.

Tra cứu bài viết Wikipedia trên bản đồ băm. Tùy thuộc vào việc triển khai nào được sử dụng, các đặc điểm về mặt tra cứu, chèn và xóa có thể khác nhau đáng kể.

Và đó là điều khiến tôi lo lắng nhất khi bổ sung unordered_mapSTL: họ sẽ phải chọn một triển khai cụ thể vì tôi nghi ngờ họ sẽ đi xuống Policy, và vì vậy chúng tôi sẽ bị mắc kẹt với việc triển khai cho sử dụng trung bình và không có gì cho các trường hợp khác ...

Ví dụ, một số bản đồ băm có chế độ luyện lại tuyến tính, trong đó thay vì làm lại toàn bộ bản đồ băm cùng một lúc, một phần được thử lại ở mỗi lần chèn, giúp khấu hao chi phí.

Một ví dụ khác: một số bản đồ băm sử dụng danh sách các nút đơn giản cho nhóm, một số bản đồ khác sử dụng bản đồ, một số khác không sử dụng nút nhưng tìm vị trí gần nhất và cuối cùng một số sẽ sử dụng danh sách các nút nhưng sắp xếp lại để phần tử được truy cập cuối cùng ở phía trước (giống như một điều lưu trữ).

Vì vậy, tại thời điểm này tôi có xu hướng thích std::maphoặc có lẽ là loki::AssocVector(đối với các tập dữ liệu bị đóng băng).

Đừng hiểu sai ý tôi, tôi muốn sử dụng std::unordered_mapvà tôi có thể trong tương lai, nhưng thật khó để "tin tưởng" tính di động của một container như vậy khi bạn nghĩ về tất cả các cách thực hiện và các màn trình diễn khác nhau dẫn đến kết quả điều này.


17
+1: điểm hợp lệ - cuộc sống dễ dàng hơn khi tôi đang sử dụng triển khai của riêng mình - ít nhất là tôi biết nó bị hút ở đâu :>
Kornel Kisielewicz

25

Sự khác biệt đáng kể chưa thực sự được đề cập đầy đủ ở đây:

  • mapgiữ các trình vòng lặp cho tất cả các phần tử ổn định, trong C ++ 17, bạn thậm chí có thể di chuyển các phần tử từ phần tử này sang phần tử mapkhác mà không làm mất hiệu lực các trình vòng lặp cho chúng (và nếu được thực hiện đúng mà không cần phân bổ tiềm năng).
  • map thời gian cho các hoạt động đơn lẻ thường phù hợp hơn vì chúng không bao giờ cần phân bổ lớn.
  • unordered_mapsử dụng std::hashnhư được triển khai trong libstdc ++ dễ bị DoS nếu được cung cấp với đầu vào không đáng tin cậy (nó sử dụng MurmurHash2 với một hạt giống không đổi - không phải việc gieo hạt đó sẽ thực sự hữu ích, xem https://emboss.github.io/blog/2012/12/14/ break-murmur-hash-lũing-dos-reloaded / ).
  • Được sắp xếp cho phép tìm kiếm phạm vi hiệu quả, ví dụ lặp lại tất cả các yếu tố với khóa ≥ 42.

14

Các bảng băm có hằng số cao hơn so với triển khai bản đồ phổ biến, điều này trở nên quan trọng đối với các thùng chứa nhỏ. Kích thước tối đa là 10, 100, hoặc thậm chí 1.000 hoặc nhiều hơn? Các hằng số vẫn giống như mọi khi, nhưng O (log n) gần với O (k). (Hãy nhớ độ phức tạp logarit vẫn thực sự tốt.)

Điều gì làm cho hàm băm tốt phụ thuộc vào đặc điểm dữ liệu của bạn; vì vậy nếu tôi không có kế hoạch xem xét hàm băm tùy chỉnh (nhưng chắc chắn có thể thay đổi suy nghĩ của tôi sau này và dễ dàng vì tôi đã gõ gần mọi thứ) và mặc dù các mặc định được chọn để thực hiện chính xác cho nhiều nguồn dữ liệu, tôi tìm thấy thứ tự bản chất của bản đồ là đủ giúp đỡ ban đầu mà tôi vẫn mặc định là bản đồ thay vì bảng băm trong trường hợp đó.

Thêm vào đó, bạn thậm chí không phải nghĩ về việc viết hàm băm cho các loại khác (thường là UDT) và chỉ cần viết op <(dù sao bạn cũng muốn).


@Roger, bạn có biết số lượng phần tử gần đúng mà bản đồ unordered_map tốt nhất không? Dù sao thì tôi cũng có thể viết một bài kiểm tra cho nó ... (+1)
Kornel Kisielewicz

1
@Kornel: Nó không mất nhiều lắm; thử nghiệm của tôi là với khoảng 10.000 yếu tố. Nếu chúng tôi muốn có một biểu đồ thực sự chính xác, bạn có thể xem xét việc triển khai mapvà một trong số đó unordered_map, với nền tảng nhất định và kích thước bộ đệm nhất định và thực hiện phân tích phức tạp. : P
GManNickG

Phụ thuộc vào chi tiết triển khai, các tham số điều chỉnh thời gian biên dịch (dễ hỗ trợ nếu bạn đang viết triển khai của riêng mình) và thậm chí cả máy cụ thể được sử dụng cho các thử nghiệm. Cũng giống như các container khác, ủy ban chỉ đặt ra các yêu cầu rộng lớn.

13

Lý do đã được đưa ra trong các câu trả lời khác; đây là một cái khác

Các hoạt động của std :: map (cây nhị phân cân bằng) được khấu hao O (log n) và trường hợp xấu nhất O (log n). Các hoạt động std :: unordered_map (bảng băm) được khấu hao O (1) và trường hợp xấu nhất O (n).

Làm thế nào điều này diễn ra trong thực tế là bảng băm "nấc" mỗi lần với thao tác O (n), có thể hoặc không phải là thứ mà ứng dụng của bạn có thể chịu đựng được. Nếu không thể chịu đựng được, bạn sẽ thích std :: map hơn std :: unordered_map.


12

Tóm lược

Giả sử đặt hàng không quan trọng:

  • Nếu bạn định xây dựng bảng lớn một lần và thực hiện nhiều truy vấn, hãy sử dụng std::unordered_map
  • Nếu bạn định xây dựng bảng nhỏ (có thể dưới 100 phần tử) và thực hiện nhiều truy vấn, hãy sử dụng std::map. Điều này là do đọc trên đó là O(log n).
  • Nếu bạn sẽ thay đổi bảng nhiều thì có thể std::map là lựa chọn tốt.
  • Nếu bạn nghi ngờ, chỉ cần sử dụng std::unordered_map.

Bối cảnh lịch sử

Trong hầu hết các ngôn ngữ, bản đồ không có thứ tự (còn gọi là từ điển dựa trên hàm băm) là bản đồ mặc định, tuy nhiên trong C ++, bạn nhận được bản đồ theo thứ tự như bản đồ mặc định. Làm thế nào điều đó xảy ra? Một số người lầm tưởng rằng ủy ban C ++ đã đưa ra quyết định này theo trí tuệ độc đáo của họ nhưng sự thật không may là xấu hơn thế.

Người ta tin rằng C ++ kết thúc với bản đồ được đặt hàng là mặc định vì không có quá nhiều tham số về cách chúng có thể được thực hiện. Mặt khác, việc triển khai dựa trên hàm băm có rất nhiều điều để nói. Vì vậy, để tránh tình trạng lưới điện trong tiêu chuẩn hóa, họ chỉ cần kết hợp với bản đồ được đặt hàng. Khoảng năm 2005, nhiều ngôn ngữ đã có triển khai tốt về triển khai dựa trên hàm băm và do đó, ủy ban chấp nhận mới dễ dàng hơn std::unordered_map. Trong một thế giới hoàn hảo, std::mapsẽ không có thứ tự và chúng ta sẽ có std::ordered_maploại riêng biệt.

Hiệu suất

Dưới đây hai biểu đồ nên nói cho chính họ ( nguồn ):

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


Dữ liệu thú vị; bạn đã bao gồm bao nhiêu nền tảng trong các bài kiểm tra của mình?
Toby Speight

1
Tại sao tôi nên sử dụng std :: map cho bảng nhỏ khi thực hiện nhiều truy vấn vì std :: unordered_map luôn hoạt động tốt hơn std :: map theo 2 hình ảnh bạn đã đăng ở đây?
ricky

Biểu đồ cho thấy hiệu suất cho các yếu tố từ 0,13M trở lên. Nếu bạn có các phần tử nhỏ (có thể là <100) thì O (log n) có thể trở nên nhỏ hơn bản đồ không có thứ tự.
Shital Shah

10

Gần đây tôi đã thực hiện một thử nghiệm làm cho 50000 hợp nhất và sắp xếp. Điều đó có nghĩa là nếu các khóa chuỗi giống nhau, hợp nhất chuỗi byte. Và đầu ra cuối cùng nên được sắp xếp. Vì vậy, điều này bao gồm một tìm kiếm cho mỗi chèn.

Để mapthực hiện, phải mất 200 ms để hoàn thành công việc. Đối với dấu unordered_map+ map, phải mất 70 ms khi unordered_mapchèn và 80 ms khi mapchèn. Vì vậy, việc thực hiện lai là nhanh hơn 50 ms.

Chúng ta nên suy nghĩ hai lần trước khi sử dụng map. Nếu bạn chỉ cần sắp xếp dữ liệu trong kết quả cuối cùng của chương trình, một giải pháp lai có thể tốt hơn.


0

Bổ sung nhỏ cho tất cả các bên trên:

Sử dụng tốt hơn map, khi bạn cần lấy các phần tử theo phạm vi, vì chúng được sắp xếp và bạn chỉ có thể lặp lại chúng từ ranh giới này sang ranh giới khác.


-1

Từ: http://www.cplusplus.com/reference/map/map/

"Trong nội bộ, các yếu tố trong bản đồ luôn được sắp xếp theo khóa của nó theo một tiêu chí đặt hàng yếu nghiêm ngặt cụ thể được chỉ định bởi đối tượng so sánh bên trong của nó (loại So sánh).

các bộ chứa bản đồ thường chậm hơn các bộ chứa unordered_map để truy cập các phần tử riêng lẻ bằng khóa của chúng, nhưng chúng cho phép lặp lại trực tiếp trên các tập hợp con dựa trên thứ tự của chúng. "

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.