เวกเตอร์เป็นคีย์ทำงานอย่างไรภายใน C ++


14

คำตอบ SO นี้บอกว่าแผนที่ STL พร้อม Vector สำหรับคีย์นั้นเวกเตอร์สามารถใช้เป็นคีย์ได้ ดังนั้นเมื่อเราใช้เวกเตอร์เป็นกุญแจ ใช้งานได้จริงอย่างไรเนื่องจากคีย์ต้องไม่ซ้ำกันดังนั้นเมื่อเราแทรกเวกเตอร์อื่นที่มีองค์ประกอบเดียวกันจะmapตรวจสอบองค์ประกอบที่ซ้ำกันตามองค์ประกอบหรือชื่อของเวกเตอร์ระบุบางอย่าง เช่นเดียวกับชื่อของอาร์เรย์หมายถึงที่อยู่ฐาน ดังนั้นอาเรย์สามารถใช้เป็นคีย์ได้เนื่องจากที่อยู่พื้นฐานสามารถใช้เป็นคีย์ในกรณีนี้ แต่คีย์ในกรณีของเวกเตอร์คืออะไร มันทำงานอย่างไรภายใน

เพราะเมื่อฉันพิมพ์ชื่อของเวกเตอร์ฉันจะได้รับข้อผิดพลาด

vector<int> v;
cout<<v; //error

คุณหมายถึงอะไรโดยการพิมพ์ชื่อเวกเตอร์
บาร์ต

has operators == and <มันช่วยได้อย่างไร คำถามของฉันคือการตรวจสอบองค์ประกอบที่ซ้ำกันจะแมปเปรียบเทียบองค์ประกอบสำคัญของเวกเตอร์ตามองค์ประกอบ
Pulkit Bhatnagar

3
@PulkitBhatnagar แต่ ... ไม่มีใครเลยที่จะบังคับให้คุณใช้เป็นกุญแจสำคัญสำหรับstd::vector คุณจ่ายสำหรับสิ่งที่คุณใช้ สามารถทำได้และอาจมีกรณีการใช้งานบางอย่าง แต่แน่นอนที่สุดคุณสามารถเปลี่ยนโครงสร้างข้อมูลที่คุณเลือก คอนเทนเนอร์ STL ได้รับการออกแบบให้มีความหลากหลายและสามารถใช้งานได้ในทุกวิถีทางที่ผู้ใช้อาจต้องการใช้ std::map
Yksisarvinen


1
@PulkitBhatnagar Stores โดยตรง std::mapจะคัดลอกคีย์และค่าลงในตัวมันเอง std::unordered_mapสามารถเก็บแฮชของกุญแจได้
Yksisarvinen

คำตอบ:


9

มีโอเปอเรเตอร์ที่โอเวอร์โหลด <สำหรับคลาสเท็มเพลต std :: vector

template <class T, 
class Allocator>
bool operator< (const vector<T, Allocator>& x, const vector<T, Allocator>& y);

std::lexicographical_compareที่เป็นไปตามขั้นตอนวิธีการมาตรฐาน

นี่คือโปรแกรมสาธิต

#include <iostream>
#include <iomanip>
#include <vector>
#include <iterator>
#include <algorithm>

int main() 
{
    std::vector<int> v1 = { 1, 2 };
    std::vector<int> v2 = { 1, 2, 3 };
    std::vector<int> v3 = { 2 };

    std::cout << std::boolalpha << ( v1 < v2 ) << '\n';
    std::cout << std::lexicographical_compare( std::begin( v1 ), std::end( v1 ),
                                               std::begin( v2 ), std::end( v2 ) )
             << '\n';                                              

    std::cout << std::boolalpha << ( v1 < v3 ) << '\n';
    std::cout << std::lexicographical_compare( std::begin( v1 ), std::end( v1 ),
                                               std::begin( v3 ), std::end( v3 ) )
             << '\n';                                              

    std::cout << std::boolalpha << ( v2 < v3 ) << '\n';
    std::cout << std::lexicographical_compare( std::begin( v2 ), std::end( v2 ),
                                               std::begin( v3 ), std::end( v3 ) )
             << '\n';                                              

    return 0;
}

เอาท์พุทมันคือ

true
true
true
true
true
true

ดังนั้นคลาสสามารถใช้เป็นกุญแจในแผนที่ได้

โดยค่าเริ่มต้นแผนที่แม่แบบชั้นเรียนใช้วัตถุฟังก์ชั่นมาตรฐาน :: น้อยกว่านั้นจะใช้ตัวดำเนินการ <

template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T>>>
class map 
{
    //...
};

อย่างไรก็ตามไม่มีโอเปอเรเตอร์ที่โอเวอร์โหลด << สำหรับเทมเพลตคลาส std :: vector


5
ฉันเห็นคำตอบของคุณเมื่อเร็ว ๆ นี้ในคำถาม C ++ เกือบทั้งหมดดังนั้นฉันไม่รู้ว่าในชีวิตทั้งชีวิตของฉันฉันจะสามารถบรรลุสิ่งที่คุณมี แต่ฉันจะพยายามอย่างดีที่สุด ขอบคุณสำหรับคำตอบ
Pulkit Bhatnagar

8

ชื่อของวัตถุและเนื้อหาของวัตถุนั้นเป็นสิ่งที่ไม่เกี่ยวข้องกันเสมอ

operator ==เพราะstd::vectorจะเปรียบเทียบความยาวของเวกเตอร์ก่อนแล้วจึงใช้องค์ประกอบแต่ละอย่างoperator ==เช่นกัน

operator <เปรียบเทียบองค์ประกอบในเวกเตอร์ lexicographically เช่นก็จะส่งกลับx[i] < y[i]สำหรับองค์ประกอบที่ไม่เท่ากันเป็นครั้งแรกในเวกเตอร์และxy

เหล่านี้เป็นความต้องการมีสำหรับประเภทที่ใช้เป็นstd::map Keyเนื่องจากทั้งสองฝ่ายก็สามารถนำมาใช้โดยเป็นstd::vector Keyโปรดทราบว่าประเภทที่จัดการโดย vector ต้องมีตัวดำเนินการเหล่านี้มากเกินไปสำหรับสิ่งนี้ในการทำงาน (เพราะstd::vectorต้องอาศัยตัวดำเนินการเหล่านั้นเพื่อใช้ตัวดำเนินการของตัวเอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.