ใช้ตั้งเมื่อ:
- เราต้องการข้อมูลที่สั่งซื้อ (องค์ประกอบที่แตกต่าง)
- เราจะต้องพิมพ์ / เข้าถึงข้อมูล (เรียงตามลำดับ)
- เราต้องการบรรพบุรุษ / ผู้สืบทอดองค์ประกอบ
ใช้ unordered_set เมื่อ:
- เราจำเป็นต้องเก็บชุดขององค์ประกอบที่แตกต่างและไม่จำเป็นต้องสั่งซื้อ
- เราต้องการการเข้าถึงองค์ประกอบเดียวคือไม่มีการแวะผ่าน
ตัวอย่าง:
ตั้ง:
อินพุต: 1, 8, 2, 5, 3, 9
เอาต์พุต: 1, 2, 3, 5, 8, 9
Unordered_set:
อินพุต: 1, 8, 2, 5, 3, 9
ผลลัพธ์: 9 3 1 8 2 5 (อาจจะเป็นคำสั่งนี้ได้รับอิทธิพลจากฟังก์ชั่นแฮช)
ความแตกต่างส่วนใหญ่:
หมายเหตุ: (ในบางกรณีset
สะดวกกว่า) ตัวอย่างเช่นใช้vector
เป็นคีย์
set<vector<int>> s;
s.insert({1, 2});
s.insert({1, 3});
s.insert({1, 2});
for(const auto& vec:s)
cout<<vec<<endl; // I have override << for vector
// 1 2
// 1 3
สาเหตุที่vector<int>
สามารถเป็นกุญแจสำคัญในset
เพราะการvector
แทนที่operator<
แทนที่
แต่ถ้าคุณใช้unordered_set<vector<int>>
คุณต้องสร้างฟังก์ชันแฮชvector<int>
เพราะ vector ไม่มีฟังก์ชันแฮชดังนั้นคุณต้องกำหนดหนึ่งอย่าง:
struct VectorHash {
size_t operator()(const std::vector<int>& v) const {
std::hash<int> hasher;
size_t seed = 0;
for (int i : v) {
seed ^= hasher(i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
};
vector<vector<int>> two(){
//unordered_set<vector<int>> s; // error vector<int> doesn't have hash function
unordered_set<vector<int>, VectorHash> s;
s.insert({1, 2});
s.insert({1, 3});
s.insert({1, 2});
for(const auto& vec:s)
cout<<vec<<endl;
// 1 2
// 1 3
}
คุณจะเห็นว่าในบางกรณี unordered_set
มีความซับซ้อนมากขึ้น
ส่วนใหญ่อ้างจาก:
https://www.geeksforgeeks.org/set-vs-unordered_set-c-stl/
https://stackoverflow.com/a/29855973/6329006