C++ - 맵 및 세트(멀티맵 및 멀티세트)

목차

1. 연관 컨테이너

2. 키-값 쌍

3. 트리 구조의 연관 컨테이너

3.1 세트

3.1.1 세트 소개

3.1.2 세트 사용

3.2 멀티셋

3.2.1 다중 집합 소개

3.2.2 다중 집합의 사용

3.3 지도

3.3.1 지도 소개

3.3.2 지도 사용

3.4 멀티맵

3.4.1 멀티맵 소개

3.4.2 멀티맵 사용

4. 운동


1. 연관 컨테이너

순차 컨테이너: vector, list, deque, forward_list(C++11) 등. 맨 아래 계층은 요소 자체를 저장하는 선형 시퀀스 데이터 구조이기 때문입니다 .
그렇다면 연관 컨테이너는 무엇입니까? 직렬 컨테이너와 어떻게 다른가요?
연관 컨테이너는 데이터를 저장하는 데에도 사용되며 순차 컨테이너와 달리 <키, 값> 구조를 저장합니다 .
데이터 검색을 위한 순차적 컨테이너보다 더 효율적인 키-값 .

2. 키-값 쌍

일대일 대응 구조를 나타내는 데 사용되며 , 일반적으로 이 구조에는 두 개의 멤버 변수인 key와 value 만 포함되며 key는 다음을 나타냅니다.
테이블 키 값, 값은 키에 해당하는 정보를 나타냅니다 .
예: 영중 사전, 영어가 키이고 해당 중국어가 값입니다.

 키의 유형은 첫 번째 템플릿의 유형이고 값의 유형은 두 번째 템플릿의 유형입니다.

stl30의 쌍 설계는 다음과 같습니다.

template <class T1, class T2>
struct pair {
  typedef T1 first_type;
  typedef T2 second_type;

  T1 first;
  T2 second;
  pair() : first(T1()), second(T2()) {}
  pair(const T1& a, const T2& b) : first(a), second(b) {}

#ifdef __STL_MEMBER_TEMPLATES
  template <class U1, class U2>
  pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {}
#endif
};

3. 트리 구조의 연관 컨테이너

트리 구조의 연관 컨테이너: 맵, 세트, ​​멀티맵, 멀티세트.

이 네 가지 컨테이너 의 공통점 : 균형 잡힌 검색 트리(즉, 레드-블랙 트리 )를 기본 결과로 사용하고 컨테이너의 요소는 순서가 있는 시퀀스입니다.

3.1 세트

3.1.1 세트 소개

문서 설정

1. set은 특정 순서로 요소를 저장하는 컨테이너입니다.
2. 세트에서 요소의 값도 이를 식별하며(값은 키이고 유형은 T임) 각 값은 고유해야 합니다.
집합의 요소는 컨테이너에서 수정할 수 없지만(요소는 항상 const임) 컨테이너에서 삽입하거나 제거할 수 있습니다.
3. 내부적으로 집합의 요소는 항상 내부 비교 개체(유형 비교)가 나타내는 특정한 엄격한 약한 순서 기준에 따라 정렬됩니다.
종류.
4. 일반적으로 set 컨테이너는 unordered_set 컨테이너보다 키로 단일 요소에 액세스하는 속도가 느리지만
하위 집합은 직접 반복됩니다.
5. 최하위 계층에 이진 검색 트리(레드-블랙 트리)로 세트를 구현합니다.
알아채다:

1. 맵/멀티맵과 달리 실제 키-값 쌍 <키, 값>은 맵/멀티맵에 저장되며,
값이지만 <value, value>로 구성된 키-값 쌍은 실제로는 최하위 계층에 저장됩니다.
2. 집합에 요소를 삽입할 때 값만 삽입하면 되며 키-값 쌍을 구성할 필요가 없습니다.
3. 집합의 요소는 반복될 수 없습니다(따라서 중복 제거를 위해 집합을 사용할 수 있음).
4. 집합 반복자를 사용하여 집합의 요소를 순회하여 정렬된 시퀀스를 얻습니다.
5. 집합의 요소는 기본적으로 다음보다 적게 비교됩니다.
6. 세트에서 요소를 찾기 위한 시간 복잡도는 다음과 같습니다. log(n)
7. 세트의 요소는 수정할 수 없습니다.
8. 집합의 최하위 레이어는 이진 검색 트리(레드-블랙 트리)를 사용하여 구현됩니다.

3.1.2 세트 사용

  1. 세트의 템플릿 매개변수 목록

T: 집합에 저장된 요소의 유형과 <값, 값>의 키-값 쌍은 실제로 맨 아래 계층에 저장됩니다.
비교(펑터): 집합의 요소는 기본적으로 다음보다 적게 비교됩니다.
Alloc : 집합 내 요소 공간의 관리 방식으로, STL에서 제공하는 space configurator를 이용하여 관리

      2. set 사용 예(문서의 기능 보기)

  • 구조

  • 반복자

  •  작업 수정

3.2 멀티셋

3.2.1 다중 집합 소개

1. multiset은 특정 순서로 요소를 저장하는 컨테이너로, 요소가 반복될 수 있습니다 .
2. multiset에서 요소의 값도 인식합니다(multiset 자체가 <value, value>의 구성을 저장하기 때문입니다.
키-값 쌍이므로 값 자체가 키이고 키가 값이며 유형은 T입니다.) 다중 집합 요소의 값은 컨테이너에 있을 수 없습니다.
(요소는 항상 const이므로) 컨테이너에서 삽입하거나 삭제할 수 있습니다 .
3. 내부적으로 multiset의 요소는 항상 내부 비교 규칙(유형 비교)에 의해 지정된 특정 엄격한 약한 정렬 기준에 따라 정렬됩니다.
종류.
4. 다중집합 컨테이너가 단일 요소에 키로 접근하는 속도는 일반적으로 무순다중집합 컨테이너보다 느리지만 반복문을 사용할 때
제너레이터가 순회되면 정렬된 시퀀스를 얻게 됩니다.
5. 다중 집합의 기본 구조는 이진 검색 트리(레드-블랙 트리)입니다.

알아채다:

1. 다중집합의 최하층에는 <값,값>의 키-값 쌍이 저장된다.
2. mtltiset의 삽입 인터페이스에만 삽입하면 됩니다.
3. set과의 차이점은 multiset의 요소는 반복될 수 있고 set의 값은 고유하다는 것입니다.
4. 반복자를 사용하여 multiset의 요소를 순회하여 정렬된 시퀀스를 얻습니다.
5. multiset의 요소는 수정할 수 없습니다.
6. 다중 집합에서 요소를 찾으십시오. 시간 복잡도는 log(N)입니다.
7. 다중 집합의 역할: 요소를 정렬할 수 있음

3.2.2 다중 집합의 사용

  • multiset.count(통계 수)  

  •  multiset.find(val) - inorder의 첫 번째 val에 대한 반복자를 반환합니다.

 

  •  multiset.erase(val) - 모든 값 삭제

3.3 지도

3.3.1 지도 소개

지도 문서

1. 맵은 키와 값으로 구성된 요소를 특정 순서(키로 비교)로 저장하는 연관 컨테이너입니다.
프라임 .
2. 맵에서 키 값 키는 일반적으로 요소를 정렬하고 고유하게 식별하는 데 사용되며 값 값은 이 키 값 키와 연결된 값을 저장합니다.
콘텐츠. key value key와 value value의 타입은 다를 수 있으며, map 내부에서는 key와 value가 멤버 타입을 전달한다.
value_type은 함께 바인딩되며 해당 별칭 이름은 pair입니다.
typedef pair<const key, T> value_type;
3. 내부적으로 맵의 요소는 항상 키 값 키에 따라 정렬됩니다.
4. 맵의 키 값으로 단일 요소에 액세스하는 속도는 일반적으로 unordered_map 컨테이너보다 느리지만 맵은 허용합니다.
요소에 대해 직접 반복합니다(즉, 맵의 요소에 대해 반복할 때 정렬된 시퀀스를 얻을 수 있음).
5. 맵은 첨자 접근자를 지원합니다 . 즉 []에 키를 넣으면 해당 키에 해당하는 값을 찾을 수 있습니다.
6. 맵은 일반적으로 이진 검색 트리(보다 정확하게는 균형 잡힌 이진 검색 트리(레드-블랙 트리))로 구현됩니다.

3.3.2 지도 사용

  1. 지도 템플릿 매개변수 설명

     2. 지도 사용

 작업은 set의 작업과 거의 동일합니다. 문서를 읽고 스스로 학습할 수 있습니다. operator[ ] 에 집중하세요.

액세스 요소:

k가 컨테이너에 있는 요소의 키와 일치 하면 함수는 매핑된 값 에 대한 참조를 반환합니다

k가 컨테이너에 있는 요소의 키와 일치하지 않는 경우 함수는 해당 키가 있는 새 요소를 삽입 하고 매핑 된 값 에 대한 참조를 반환합니다 . 이렇게 하면 매핑된 값이 요소에 할당되지 않은 경우에도 항상 컨테이너 크기가 1씩 증가합니다(요소는 기본 생성자를 사용하여 구성됨 ).

참고: 요소에 액세스할 때 operator[]와 유사한 at()(이 함수는 일반적으로 사용되지 않음) 함수가 있습니다.
key는 키에 해당하는 값을 찾은 다음 해당 참조를 반환합니다. 차이점은 다음과 같습니다. 키가 존재하지 않으면 operator[]는 기본값을 사용합니다.
값과 키는 키-값 쌍을 구성한 다음 이를 삽입하고 기본값을 반환하며 at() 함수는 직접 예외를 발생시킵니다 .

요약하다:

  • 지도::연산자[ ]

1. 맵에 이 키가 있고 값에 대한 참조가 반환됩니다. (값 찾기, 수정)

2. 맵에 해당 키가 없으면 pair(key, V())가 삽입되고 값에 대한 참조가 반환됩니다. (삽입 + 수정)

  •  지도::삽입

1. 키가 이미 맵에 있으므로 pair(key_iterator, false)를 반환합니다.

2. 키가 맵에 없으면 pair(new_key_iterator, true) 반환

3.4 멀티맵

3.4.1 멀티맵 소개

1. 멀티맵은 특정 순서 <key,
value>, 여러 키-값 쌍 사이의 키가 반복될 수 있습니다 .
2. 멀티맵에서 요소는 일반적으로 키에 따라 정렬되고 고유하게 식별되며 매핑된 값은 키와 연결된 콘텐츠를 저장합니다.
허용하다. key와 value의 타입은 다를 수 있으며 multimap 내부의 value_type 멤버 타입을 통해 결합되며,
value_type은 키와 값을 결합하는 키-값 쌍입니다.
typedef 쌍<const 키, T> value_type;
3. 내부적으로 multimap의 요소는 항상 내부 비교 개체에서 지정한 특정 엄격한 약한 순서 지정 기준에 따라 정렬됩니다.
키가 정렬되었습니다.
4. 키로 단일 요소에 액세스하는 multimap의 속도는 일반적으로 unordered_multimap 컨테이너보다 느리지만 반복을 사용합니다.
연산자는 순서가 지정된 키 시퀀스를 얻기 위해 multimap의 요소를 직접 순회합니다.
5. 멀티맵은 최하위 계층에 이진 검색 트리(레드-블랙 트리)로 구현됩니다.
참고: multimap과 map의 유일한 차이점은 map의 키는 고유한 반면 multimap의 키는
반복 .

3.4.2 멀티맵 사용

multimap의 인터페이스는 map을 참조할 수 있으며 기능은 유사합니다.
알아채다:
1. multimap의 키는 반복될 수 있습니다.
2. 기본적으로 multimap의 요소는 키를 다음보다 작은 것으로 비교합니다.
3. multimap에는 오버로드된 operator[] 작업이 없습니다.
4. 사용시 맵에 포함된 헤더 파일과 동일

4. 운동

마지막으로 지도와 집합에 대한 연습문제 2개를 더 게시합니다 이론+실습으로 글을 써보셔도 되고 직접 이해하시면 정말 이해가 되실거에요!

상위 K 빈도 단어 https://leetcode.cn/problems/top-k-frequent-words/description/

class Solution {
public:
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string,int>Countmap;
        //map[]插入+修改实现统计
        for(auto& str:words)
        {
            Countmap[str]++;
        }
        //比较次数,我们把次数作为Key,降序排
        multimap<int,string,greater<int>>sortmap;
        for(auto& kv:Countmap)
        {
            sortmap.insert(make_pair(kv.second,kv.first));
        }
        vector<string>v;
        multimap<int,string,greater<int>>::iterator it=sortmap.begin();
        while(k--)
        {
            v.push_back(it->second);
            ++it;
        }
        return v;
    }
};
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        //找交集(有序):小的往后走,相等找到存入并同时走
        set<int>s1(nums1.begin(),nums1.end());
        set<int>s2(nums2.begin(),nums2.end());

        auto it1=s1.begin();
        auto it2=s2.begin();
        vector<int>v;
        while(it1!=s1.end()&&it2!=s2.end())
        {
            if(*it1<*it2)
            {
                ++it1;
            }
            else if(*it2<*it1)
            {
                ++it2;
            }
            else
            {
                v.push_back(*it1);
                ++it1;
                ++it2;
            }
        }
        return v;
    }
};

Supongo que te gusta

Origin blog.csdn.net/bang___bang_/article/details/131768362
Recomendado
Clasificación