1. 程式人生 > >STL的學習之(一)list和pair對組的使用

STL的學習之(一)list和pair對組的使用

一,list容器的使用

一些api的說明

  1. 成員函式(建構函式)
  2. 構造 list (公開成員函式)
  3. (解構函式) 析構 list (公開成員函式)
  4. operator= 賦值給容器 (公開成員函式)
  5. assign 將值賦給容器 (公開成員函式)
  6. get_allocator 返回相關的分配器 (公開成員函式) 元素訪問
  7. front 訪問第一個元素 (公開成員函式) [編輯]
  8. back 訪問最後一個元素 (公開成員函式) [編輯]
  9. 迭代器 begin cbegin 返回指向容器第一個元素的迭代器 (公開成員函式) [編輯] end cend
    返回指向容器尾端的迭代器 (公開成員函式) [編輯] rbegin crbegin

  10. 返回一個指向容器最後一個元素的反向迭代器 (公開成員函式) [編輯] rend crend 返回一個指向容器前端的反向迭代器
    (公開成員函式) [編輯]

  11. 容量 empty 檢查容器是否為空 (公開成員函式) [編輯]
  12. size 返回容納的元素數 (公開成員函式) [編輯]
  13. max_size 返回可容納的最大元素數 (公開成員函式) [編輯]

修改器

  1. clear 清除內容 (公開成員函式) [編輯]
  2. insert 插入元素 (公開成員函式) [編輯]
  3. emplace (C++11) 原位構造元素 (公開成員函式) [編輯]
  4. erase 擦除元素 (公開成員函式) [編輯]
  5. push_back 將元素新增到容器末尾 (公開成員函式) [編輯]
  6. emplace_back (C++11) 在容器末尾就地構造元素 (公開成員函式) [編輯]
  7. pop_back 移除末元素 (公開成員函式) [編輯]
  8. push_front 插入元素到容器起始 (公開成員函式) [編輯]
  9. emplace_front (C++11) 在容器頭部就地構造元素 (公開成員函式) [編輯]
  10. pop_front 移除首元素 (公開成員函式) [編輯]
  11. resize 改變容器中可儲存元素的個數 (公開成員函式) [編輯]
  12. swap 交換內容 (公開成員函式) [編輯]

操作

  1. merge 合併二個已排序列表 (公開成員函式) [編輯]
  2. splice 從另一個list中移動元素 (公開成員函式) [編輯]
  3. remove, remove_if 刪除滿足特定條件的元素 (公開成員函式) [編輯]
  4. reverse 將該連結串列的所有元素的順序反轉 (公開成員函式) [編輯]
  5. unique 刪除連續的重複元素 (公開成員函式) [編輯]
  6. sort 對元素進行排序 (公開成員函式) [編輯]

非成員函式
operator==
operator!=
operator<
operator<=
operator>
operator>=
根據字典順序比較 list 中的值
(函式模板) [編輯]
std::swap(std::list)
特化 std::swap 演算法
(函式模板) [編輯]
推導指引(C++17 起)

1,remove刪除操作自定義的資料型別的要重寫成員函式operator==函式

自定義資料
class Person
{
public:
    string m_name;
    int m_age;
    int m_height;

    Person(string name, int age, int height)
    {
        this->m_name = name;
        this->m_age = age;
        this->m_height = height;
    }

     //重寫==成員函式
    bool operator==(const Person& p)
    {
        if ((this->m_age == p.m_age) && this->m_height == p.m_height && this->m_name == p.m_name)
            return true;
        return false;
    }
    //重寫<函式
    bool operator<(const Person& p)
    {
        if (this->m_age == p.m_age)
            return (this->m_height < p.m_height);
        return (this->m_age < p.m_age);
    }

    bool operator()(Person& p) const
    {
        if ((this->m_age == p.m_age) && this->m_height == p.m_height && this->m_name == p.m_name)
            return true;
        return false;
    }
};


void printfPerson(const list<Person> & l)
{
    for (list<Person>::const_iterator it = l.begin(); it != l.end(); it++)
    {
        cout << "姓名:" << (*it).m_name << ", 年齡:" << (*it).m_age << ", 身高:" << (*it).m_height << endl;
    }
}
bool PersonComplate( Person p1,  Person p2)
{
    if (p1.m_age == p2.m_age)
        return (p1.m_height < p2.m_height);
    return (p1.m_age < p2.m_age);
}

void test01()
{
    list<Person> l;
    Person p1("陳麗", 22, 160);
    Person p2("王蓉", 21, 158);
    Person p3("王盼盼", 23, 165);

    l.insert(l.begin(), p1);
    l.insert(l.begin(), p2);
    l.push_back(p3);




    printfPerson(l);


    //倒序
    l.reverse();


    cout << "-----------倒序-----------------" << endl;
    printfPerson(l);


    list<Person> l2;


    l2.swap(l);

    cout << "-----------l2---------------" << endl;
    l2.push_front(Person("巍盼盼", 23, 150));
    printfPerson(l2);

    cout << "----------升序-------------" << endl;
    //排序
    l2.sort(PersonComplate);


    printfPerson(l2);


    cout << "-----------remove操作-----------" << endl;
    //就是這步重寫的
    l2.remove(p2);

    printfPerson(l2);


    cout << "-------------splice-----------" << endl;

    l2.splice(l.begin(), l2);

    //Person p = l2.back();
    //cout << p.m_name << endl;
    printfPerson(l2);



//  l2.assign(2, p3);


    cout << "------------------------remove_if 過載()運算子--------------" << endl;
    l2.remove_if(p1);
    printfPerson(l2);

    cout << "------------------------merage 過載()運算子--------------" << endl;
    l2.push_back(p1);
    l2.insert(l2.begin(), Person("aa", 3, 45));

    l2.merge(l);

    printfPerson(l2);
}
void printfint(const list<int> l)
{
    for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
        cout << (*it) << " ";
    cout << endl;
}
void test02()
{
    list<int> l;

    l.push_back(454);
    l.push_back(44);
    l.push_back(45);
    l.push_back(4154);

    printfint(l);
    cout << "---------------remove_if ----------------" << endl;
    //l.remove_if(44);
    list<int> l2;
    l2.push_back(8989);

    l2.merge(l);

    printfint(l);
}

int main(int argc, char *argv[])
{

    test01();
    //test02();
    system("pause");
    return 0;
}

為什麼重寫是因為資料型別沒有指明看原始碼


    void remove(const _Ty& _Val)
        {   // erase each element matching _Val
        iterator _Val_it = end();

        for (iterator _First = begin(); _First != end(); )
           //過載operator==的操作
            if (*_First == _Val)
                if (_STD addressof(*_First) == _STD addressof(_Val))
                    _Val_it = _First++;
                else
                    _First = erase(_First);
            else
                ++_First;

        if (_Val_it != end())
            erase(_Val_it);
        }

splice操作

將一個列表中的元素移動到另外一個列表中.

#include <iostream>
#include <list>

std::ostream& operator<<(std::ostream& ostr, const std::list<int>& list)
{
    for (auto &i : list) {
        ostr << " " << i;
    }
    return ostr;
}

int main ()
{
    std::list<int> list1 = { 1, 2, 3, 4, 5 };
    std::list<int> list2 = { 10, 20, 30, 40, 50 };

    auto it = list1.begin();
    std::advance(it, 2);

    list1.splice(it, list2);

    std::cout << "list1: " << list1 << "\n";
    std::cout << "list2: " << list2 << "\n";

    list2.splice(list2.begin(), list1, it, list1.end());

    std::cout << "list1: " << list1 << "\n";
    std::cout << "list2: " << list2 << "\n";
}

輸出結果

list1:  1 2 10 20 30 40 50 3 4 5
list2:
list1:  1 2 10 20 30 40 50
list2:  3 4 5

自定義型別的使用lower_bound,upper_bound , equal_range函式的呼叫

自定義資料型別要對函式過載的操作要看原始碼

template<class _FwdIt,
    class _Ty> inline
    _FwdIt lower_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
    {   // find first element not before _Val, using operator<   告訴我們要過載運算子operator<的操作
    return (_STD lower_bound(_First, _Last, _Val, less<>()));
    }

具體的實現如下:

class Person
{
    //friend bool operator()(const Person& p1, const Person& p2) const;
public:
    string m_Name;
    int m_age;
    Person(string name, int age) :m_Name(name), m_age(age) {}

    bool operator()(const Person& p) const;
    bool operator<(const Person& p) const
    {
        return (this->m_age < p.m_age);
    }
};

bool Person::operator()(const Person& p) const
{
    return (this->m_age == p.m_age);
}

void test01()
{

    set<Person> s;
    s.insert(Person("陳麗", 22));
    s.insert(Person("王盼盼", 23));
    s.insert(Person("王蓉", 21));
    s.insert(Person("巍盼盼", 20));
    Person p("楊豔", 25);
    s.insert(p);
    set<Person>::iterator pos = lower_bound(s.begin(), s.end(), p);
    pos = upper_bound(s.begin(), s.end(), p);

    //對組的使用pair 
    pair<set<Person>::iterator, set<Person>::iterator> poi = equal_range(s.begin(), s.end(), p);
    if (pos != s.end())
    {
        cout << "pos = " << pos->m_Name << endl;
    }

    /*Person p2("的李開復", 23);
    p(p2);*/

}


int main(void)
{
    test01();


    system("pause");
    return 0;
}

map容器的操作

  1. 成員函式 (建構函式)
  2. 構造 map (公開成員函式) [編輯]
  3. (解構函式) 析構 map (公開成員函式) [編輯]
  4. operator= 賦值給容器 (公開成員函式) [編輯]
  5. get_allocator 返回相關的分配器 (公開成員函式) [編輯]

元素的訪問

  1. at (C++11) 訪問指定的元素,同時進行越界檢查 (公開成員函式) [編輯] operator[] 訪問指定的元素
    (公開成員函式) [編輯]

迭代器

  1. begin cbegin 返回指向容器第一個元素的迭代器 (公開成員函式) [編輯] end cend

  2. 返回指向容器尾端的迭代器 (公開成員函式) [編輯] rbegin crbegin

  3. 返回一個指向容器最後一個元素的反向迭代器 (公開成員函式) [編輯] rend crend

返回一個指向容器前端的反向迭代器
(公開成員函式) [編輯]
容量

  1. empty 檢查容器是否為空 (公開成員函式) [編輯]
  2. size 返回容納的元素數 (公開成員函式) [編輯]
  3. max_size 返回可容納的最大元素數 (公開成員函式) [編輯]

修飾符

  1. clear 清除內容 (公開成員函式) [編輯]
  2. insert 插入元素或結點 (C++17 起) (公開成員函式) [編輯]
  3. emplace (C++11) 原位構造元素 (公開成員函式) [編輯]
  4. emplace_hint (C++11) 使用hint就地構造元素 (公開成員函式) [編輯]
  5. erase 擦除元素 (公開成員函式) [編輯]
  6. swap 交換內容 (公開成員函式) [編輯]

查詢

  1. count 返回匹配特定鍵的元素數量 (公開成員函式) [編輯]
  2. find 尋找帶有特定鍵的元素 (公開成員函式) [編輯]
  3. equal_range 返回匹配特定鍵的元素範圍 (公開成員函式) [編輯]
  4. lower_bound 返回一個迭代器,指向第一個“不小於”給定值的元素 (公開成員函式) [編輯]
  5. upper_bound 返回一個迭代器,指向第一個“大於”給定值的元素 (公開成員函式) [編輯]

觀察器

  1. key_comp 返回用於比較鍵的函式 (公開成員函式) [編輯]
  2. value_comp 返回用於在value_type型別的物件中比較鍵的函式。 (公開成員函式) [編輯]

非成員函式
operator==
operator!=
operator<
operator<=
operator>
operator>=
根據字典順序比較 map 中的值
(函式模板)

對組的定義pair

  1. pair是key-value的形式
  2. pair在和make_pair 在原始碼和pair對組是連結一起的
    // TEMPLATE FUNCTION make_pair
template<class _Ty1,
    class _Ty2>
    constexpr pair<typename _Unrefwrap<_Ty1>::type, typename _Unrefwrap<_Ty2>::type>
        make_pair(_Ty1&& _Val1, _Ty2&& _Val2)
    {   // return pair composed from arguments
    using _Mypair = pair<typename _Unrefwrap<_Ty1>::type, typename _Unrefwrap<_Ty2>::type>;
    return (_Mypair(_STD forward<_Ty1>(_Val1), _STD forward<_Ty2>(_Val2)));
    }

在原始碼的中

template<class _Ty1,
    class _Ty2>
    struct pair
    {   // store a pair of values
    using first_type = _Ty1;
    using second_type = _Ty2;

map容器的四中插入


    map<int, string> m;

    //插入資料方式
    m.insert(pair<int, string>(1, "陳麗"));

    m.insert(make_pair<int, string>(2, "王蓉"));

    m.insert(map<int, string>::value_type(3, "王盼盼"));

    m[4] = "巍盼盼";