In che modo un vettore come chiave funziona internamente in C ++?


14

Questa risposta SO afferma che la Mappa STL con un vettore per la chiave può essere utilizzata come chiave. Quindi quando usiamo un vettore come chiave. Come funziona effettivamente poiché la chiave deve essere univoca, quindi quando inseriamo un altro vettore con gli stessi elementi il mapcontrollo di elementi duplicati per elemento o il nome del vettore specifica qualcosa? Come il nome dell'array rappresenta l'indirizzo di base. Quindi un array può essere usato come chiave poiché l'indirizzo base può essere usato come chiave in questo caso, ma qual è la chiave in caso di un vettore. Come funziona internamente.

Perché quando stampo il nome del vettore, ricevo un errore

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

Cosa intendi con la stampa del nome del vettore?
Bart,

has operators == and <come può essere d'aiuto? la mia domanda era di verificare che gli elementi duplicati
mappassero

3
@PulkitBhatnagar Ma ... Nessuno ti costringerà mai a usare std::vectorcome chiave per std::map. Paghi per quello che usi . Può essere fatto, e forse ci sono alcuni casi d'uso per questo, ma sicuramente puoi cambiare la struttura dei dati che preferisci. I contenitori STL sono progettati per essere estremamente versatili e utilizzabili in qualsiasi modo l'utente possa desiderare di usarli.
Yksisarvinen,


1
@PulkitBhatnagar Stores direttamente. std::mapcopierà sia la chiave che il valore in se stesso. std::unordered_mappuò memorizzare l'hash della chiave.
Yksisarvinen,

Risposte:


9

Esiste un operatore sovraccarico <per il modello di classe std :: vector.

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

che si basa sull'algoritmo standard std::lexicographical_compare.

Ecco un programma dimostrativo.

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

Il suo output è

true
true
true
true
true
true

Quindi la classe può essere utilizzata come chiave nella mappa.

Per impostazione predefinita, la mappa del modello di classe utilizza l'oggetto funzione std :: less che a sua volta utilizza l'operatore <

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

Tuttavia non esiste un operatore sovraccarico << per il modello di classe std :: vector.


5
Vedo le tue risposte di recente in quasi tutte le domande C ++ su SO, non so se in tutta la mia vita sarò mai in grado di ottenere quello che hai, ma farò del mio meglio. Grazie per la risposta
Pulkit Bhatnagar,

8

Il nome di un oggetto e il contenuto di quell'oggetto sono sempre cose non correlate.

operator ==per std::vectorprima confronterà la lunghezza dei vettori e poi anche ciascuno dei suoi elementi usando operator ==.

operator <confronta gli elementi nel vettore lessicograficamente, cioè ritorna x[i] < y[i]per il primo elemento non uguale in vettori xe y.

Questi sono i requisiti richiesti std::mapper un tipo usato come Key. Poiché std::vectorsoddisfa entrambi, può essere utilizzato da as Key. Si noti che anche il tipo gestito da vector deve sovraccaricare questi operatori affinché funzioni (perché std::vectorsi basa su quegli operatori per implementare i propri operatori).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.