Як вектор як ключ працює внутрішньо в C ++?


14

Ця відповідь відповідає, що STL-карта з вектором для ключа вектор може використовуватися як ключ. Отже, коли ми використовуємо вектор як ключ. Як це насправді працює, оскільки ключ повинен бути унікальним, тому коли ми вставляємо інший вектор з тими ж елементами, буде mapперевірка на повторність елемента за елементом чи ім'я вектора щось визначає? Як і ім'я масиву представляє базову адресу. Отже, масив може бути використаний як ключ, оскільки в цьому випадку базова адреса може використовуватися як ключ, але що є ключовим у випадку вектора. Як це працює всередині.

Тому що, коли я друкую ім'я вектора, я отримую помилку

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

Що ви маєте на увазі, друкуючи ім'я вектора?
Барт

has operators == and <як це допомагає? моє запитання - перевірити дублюючі елементи, буде карта порівняти векторний ключовий елемент за елементами
Pulkit Bhatnagar,

3
@PulkitBhatnagar Але ... Ніхто ніколи не змусить вас використовувати його std::vectorяк ключ std::map. Ви платите за те, що використовуєте . Це можна зробити, і, можливо, для цього є деякі випадки використання, але, безумовно, ви можете змінити структуру даних, що вибираєте. Контейнери STL розроблені таким чином, щоб бути максимально універсальними та зручними для використання будь-яким способом, коли користувач зможе їх використати.
Yksisarvinen


1
@PulkitBhatnagar Магазини безпосередньо. 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

Тож клас може використовуватися як ключ у карті.

За замовчуванням карта шаблону класу використовує функцію об'єкта std :: менше, що в свою чергу використовує оператор <

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

Однак для шаблону класу std :: vector немає перевантаженого оператора <<.


5
Нещодавно я бачу ваші відповіді майже в усіх питаннях С ++ про СО, я не знаю, чи зможу я все життя досягти того, що у вас є, але я спробую все можливе. Дякую за відповідь
Pulkit Bhatnagar

8

Назва об'єкта та зміст цього об'єкта - це завжди непов'язані речі.

operator ==для std::vectorпершої буде порівнювати довжину векторів , а потім кожен з його елементів з використанням , operator ==а також.

operator <порівнює елементи у векторній лексикографічно, тобто повертається x[i] < y[i]для першого нерівного елемента у векторах xі y.

Ці вимоги пред'являються std::mapдо типу, що використовується як Key. Оскільки std::vectorзадовольняє обидва, його можна використовувати як Key. Зауважте, що тип, керований вектором, також повинен перевантажувати ці оператори, щоб це працювало (тому що він std::vectorпокладається на те, щоб реалізувати власні оператори).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.