Maksud saya adalah - kita tahu bahwa std::map
elemen diurutkan sesuai dengan kunci. Jadi, katakanlah kuncinya adalah bilangan bulat. Jika saya iterate dari std::map::begin()
ke std::map::end()
menggunakan for
, apakah jaminan standar bahwa saya akan iterate akibatnya melalui unsur-unsur dengan kunci, diurutkan dalam urutan menaik?
Contoh:
std::map<int, int> map_;
map_[1] = 2;
map_[2] = 3;
map_[3] = 4;
for( std::map<int, int>::iterator iter = map_.begin();
iter != map_.end();
++iter )
{
std::cout << iter->second;
}
Apakah ini dijamin untuk dicetak 234
atau apakah penerapannya ditentukan?
Alasan kehidupan nyata: Saya memiliki std::map
dengan int
kunci. Dalam situasi yang sangat langka, saya ingin beralih melalui semua elemen, dengan kunci, lebih besar dari int
nilai konkret . Ya, sepertinya ini std::vector
akan menjadi pilihan yang lebih baik, tetapi perhatikan "situasi yang sangat langka" saya.
EDIT : Saya tahu, bahwa elemen std::map
diurutkan .. tidak perlu menunjukkannya (untuk sebagian besar jawaban di sini). Saya bahkan menulisnya di pertanyaan saya.
Saya bertanya tentang iterator dan pesanan ketika saya beralih melalui wadah. Terima kasih @ Gerrek SB untuk jawabannya.
sumber
map::upper_bound
untuk menemukan titik untuk memulai iterasi.Jawaban:
Ya, itu dijamin. Selain itu,
*begin()
memberi Anda elemen terkecil dan*rbegin()
terbesar, seperti yang ditentukan oleh operator perbandingan, dan dua nilai kuncia
danb
untuk mana ekspresi!compare(a,b) && !compare(b,a)
itu benar dianggap sama. Fungsi perbandingan default adalahstd::less<K>
.Pemesanan bukanlah fitur bonus keberuntungan, melainkan merupakan aspek mendasar dari struktur data, karena pemesanan digunakan untuk menentukan kapan dua kunci adalah sama (dengan aturan di atas) dan untuk melakukan pencarian yang efisien (pada dasarnya biner pencarian, yang memiliki kompleksitas logaritmik dalam jumlah elemen).
sumber
std::unordered_map
memiliki waktu pencarian O (1) yang lebih efisien. Keuntungannyastd::map
adalah dalam pemesanan kunci, tetapi tidak mencari.Ini dijamin oleh persyaratan wadah asosiatif dalam standar C ++. Misalnya lihat 23.2.4 / 10 dalam C ++ 11:
dan 23.2.4 / 11
sumber
Saya pikir ada kebingungan dalam struktur data.
Dalam sebagian besar bahasa, a
map
hanyalah sebuah AssociativeContainer: a memetakan kunci nilai. Dalam bahasa "yang lebih baru", ini umumnya dicapai menggunakan peta hash, sehingga tidak ada pesanan yang dijamin.Namun dalam C ++, ini tidak begitu:
std::map
adalah wadah asosiatif yang diurutkanstd::unordered_map
adalah wadah asosiatif berbasis tabel hash yang diperkenalkan di C ++ 11Jadi, untuk memperjelas jaminan pemesanan.
Di C ++ 03:
std::set
,std::multiset
,std::map
Danstd::multimap
dijamin akan dipesan sesuai tombol (dan kriteria yang disediakan)std::multiset
danstd::multimap
, standar tidak memaksakan jaminan pesanan pada elemen yang setara (yaitu, yang membandingkan sama)Dalam C ++ 11:
std::set
,std::multiset
,std::map
Danstd::multimap
dijamin akan dipesan sesuai tombol (dan kriteria yang disediakan)std::multiset
danstd::multimap
, Standar memaksakan bahwa elemen yang setara (elemen yang sebanding) dipesan sesuai dengan urutan penyisipannya (pertama kali disisipkan terlebih dahulu)std::unordered_*
kontainer, seperti namanya, tidak dipesan. Terutama, urutan elemen dapat berubah ketika wadah dimodifikasi (setelah penyisipan / penghapusan).Ketika Standar mengatakan bahwa elemen dipesan dengan cara tertentu, itu berarti:
Saya harap ini membersihkan semua kebingungan.
sumber
Ya,
std::map
adalah wadah yang diurutkan, dipesan olehKey
bersama dengan yang disediakanComparator
. Jadi dijamin.Itu pasti mungkin.
sumber
Ya ... elemen dalam a
std::map
memiliki urutan lemah yang ketat, artinya elemen akan terdiri dari satu set (yaitu, tidak akan ada pengulangan kunci yang "sama"), dan kesetaraan ditentukan dengan menguji pada setiap dua kunci A dan B, bahwa jika kunci A tidak kurang dari kunci B, dan B tidak kurang dari A, maka kunci A sama dengan kunci B.Yang sedang berkata, Anda tidak bisa mengurutkan elemen-elemen dari a
std::map
jika urutan lemah untuk tipe itu ambigu (dalam kasus Anda, di mana Anda menggunakan integer sebagai tipe-kunci, itu bukan masalah). Anda harus dapat mendefinisikan operasi yang mendefinisikan urutan total pada jenis yang Anda gunakan untuk kunci di Andastd::map
, jika tidak, Anda hanya akan memiliki pesanan parsial untuk elemen Anda, atau poset, yang memiliki properti di mana A mungkin tidak dapat dibandingkan dengan B. Apa yang biasanya akan terjadi dalam skenario ini adalah bahwa Anda akan dapat memasukkan pasangan kunci / nilai, tetapi Anda mungkin berakhir dengan pasangan kunci / nilai duplikat jika Anda mengulangi seluruh peta, dan / atau mendeteksi "hilang" pasangan kunci / nilai ketika Anda mencoba melakukanstd::map::find()
pasangan kunci / nilai tertentu di peta.sumber
begin () dapat memberikan elemen terkecil. Tetapi implementasi tergantung. Apakah ini ditentukan dalam standar C ++? Jika tidak, maka berbahaya untuk membuat asumsi ini.
sumber