C ++에서 키로서의 벡터는 어떻게 내부적으로 작동합니까?


14

이 SO 답변에 따르면 벡터에 대한 벡터가있는 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이 레드-블랙 트리로 구현 된 이유 를 참조하십시오 . .
다니엘 랭거

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

따라서 클래스는 맵에서 키로 사용될 수 있습니다.

기본적으로 클래스 템플릿 맵은 std :: less 함수 객체를 사용합니다.

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 ==for std::vector는 먼저 벡터의 길이를 비교 한 다음 사용하는 각 요소를 비교 operator ==합니다.

operator <벡터의 요소를 사전 식으로 비교합니다. 즉, x[i] < y[i]벡터 x와 의 첫 번째 같지 않은 요소를 반환 합니다 y.

std::map사용되는 유형에 대한 요구 사항 이 Key있습니다. 이후 std::vector모두 만족이를 등으로 사용될 수있다 Key. 벡터에 의해 관리되는 유형에는이 연산자가 오버로드되어 있어야 작동합니다 ( std::vector자체 연산자를 구현하려면 해당 연산자에 의존 하기 때문에 ).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.