5. STL编程五

1. STL的六大组件:

  容器(Container)

  算法(Algorithm)

  迭带器(Iterator)

  仿函数(Function object)

  适配器(Adaptor)

  空间配置器(allocator)

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;

int main()
{
    //容器:
    vector<int> myint{ 1,2,3,4,5 };    
    myint.push_back(10);

    //算法:
    for_each(myint.begin(), myint.end(), [](int x) {cout << x <<" "; });
    cout << endl;
    
    //迭带器:
    auto it = myint.begin() + 2;
    for (auto ib = myint.begin(), ie = myint.end(); ib != ie; ib++)
    {
        cout << *ib << " ";
    }
    cout << endl;

    list<int> mylist{ 1,2,3,4,5 };
    mylist.push_front(10);
    //auto ib1 = mylist.begin() + 2;    //链表每次只能前进一个
    auto ib1 = mylist.begin()++;        //迭带器自动适应容器

    for_each(mylist.begin(), mylist.end(), [](int x) {cout << x << " "; });
    cout << endl;

    system("pause");
    return 0;
}

    

2. 容器类别:

  序列式容器:排列次序取决于插入时机和位置

  关联式容器:排列次序取决于特定准则

    

  2.1 线性容器 ( array ):

#include <iostream>
#include <array>
#include <algorithm>
using namespace std;

//array容器在栈区,自动回收内存,不能增删查改,
int main()
{
    array<int, 10> MyArr{ 1,2,3,4,5,6,7,8,9,0 };
    for (auto ib = MyArr.begin(), ie = MyArr.end(); ib != ie; ib++)
    {
        //cout << typeid(ib).name() << ": ";
        cout << *ib << " ";
    }
    cout << endl;

    for (auto i:MyArr)
    {
        cout << i << " ";
    }
    cout << endl;

    for_each(MyArr.begin(), MyArr.end(), [](int & x) {x += 1; });
    for_each(MyArr.begin(), MyArr.end(), [](int x) {cout << x << " "; });
    cout << endl;

    system("pause");
    return 0;
}

    

  2.2 线性容器 ( vector ):

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//vector在堆区,可以增删查改,
int main()
{
    vector<int> MyVec{ 1,2,3,4,5,6,7,8,9,0 };
    for (auto ib = MyVec.begin() + 3, ie = MyVec.end(); ib != ie; ib++)    //vector迭带器可以+3
    {
        cout << *ib << " ";
    }
    cout << endl;

    for (auto i : MyVec)
    {
        cout << i << " ";
    }
    cout << endl;

    for_each(MyVec.begin(), MyVec.end(), [](int & x) {x += 1; });
    for_each(MyVec.begin(), MyVec.end(), [](int x) {cout << x << " "; });
    cout << endl;

    system("pause");
    return 0;
}

    

  2.3 线性容器 ( forwardlist ):单链表( forward:前进 )==>只能前进,不能后退

#include <iostream>
#include <forward_list>    //单链表(forward:前进)==>只能前进,不能后退
#include <algorithm>
using namespace std;

int main()
{
    forward_list<int> my{ 1,2,3,4,5,6,7,8,9,0 };
    for (auto ib = my.begin(), ie = my.end(); ib != ie; ib++)    //ib++可以;但是ib--不行
    {
        cout << *ib << " ";
    }
    cout << endl;

    for (auto i : my)
    {
        cout << i << " ";
    }
    cout << endl;

    for_each(my.begin(), my.end(), [](int & x) {x += 1; });
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    system("pause");
    return 0;
}

    

  2.4 线性容器 ( list ):双链表==>既可以前进,也可以后退

#include <iostream>
#include <list>            //双链表
#include <algorithm>
using namespace std;

int main()
{
    list<int> my{ 1,2,3,4,5,6,7,8,9,0 };
    for (auto ib = my.begin(), ie = my.end(); ib != ie; ib++)    //ib++,ib--可以;但是ib+3不行
    {
        cout << *ib << " ";
    }
    cout << endl;

    for (auto i : my)
    {
        cout << i << " ";
    }
    cout << endl;

    for_each(my.begin(), my.end(), [](int & x) {x += 1; });
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    system("pause");
    return 0;
}

    

  2.5 线性容器 (deque): 双端队列(分块) ==>性能综合的要求(增、删、查、改)

#include <iostream>
#include <deque>    //双端队列(分块数据模型),在堆上
#include <algorithm>
using namespace std;

int main()
{
    deque<int> my{ 1,2,3,4,5,6,7,9 };
    cout << "最大容量:" << my.max_size() << endl;    //最大容量由内存决定
    cout << "当前容量:" << my.size() << endl;
    cout << "第一个元素:" << my.front() << endl;
    cout << "最后一个元素:" << my.back() << endl;

    for (auto ib = my.begin(), ie = my.end(); ib != ie; ib++)    
    {
        cout << *ib << " ";
    }
    cout << endl;

    for (auto i : my)
    {
        cout << i << " ";
    }
    cout << endl;

    for_each(my.begin(), my.end(), [](int & x) {x += 1; });
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    system("pause");
    return 0;
}

    

    deque的应用:

#include <iostream>
#include <deque>    //双端队列(分块数据模型),在堆上
#include <algorithm>
using namespace std;

int main()
{
    deque<int> my{ 1,2,3,4,5,6,7,9 };
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    my.push_back(10);                  //尾部插入数据10
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    my.push_front(101);                //头部插入
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    my.insert(my.begin() + 5, 99);    //任意位置插入
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    my.pop_front();              //头部删除
    my.pop_back();               //尾部删除
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    my.erase(my.begin() + 4);    //任意位置删除
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    for (int i = 0; i < my.size(); i++)
    {
        cout << my[i] << " ";        //可以用[]访问其中的元素,类模板中重载了[]
    }
    cout << endl;

    for (auto cb = my.cbegin(), ce = my.cend(); cb != ce; cb++)    //cbegin(),cend()是常量迭代器;c表示const(只读)
    {
        cout << *cb << " ";
        //*cb = 1;    //常量迭代器,只能读,不能写
    }
    cout << endl;

    my.clear();        //清空
    for_each(my.begin(), my.end(), [](int x) {cout << x << " "; });
    cout << endl;

    system("pause");
    return 0;
}

    

  2.6 线性容器 ( stack ): 栈

#include <iostream>
#include <stack>    //
#include <list>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    stack<int> myStack;                    //数组栈;stack默认底层是有deque实现的(因为deque的删除、插入性能也比较高)
    stack<int, list<int>> myListStack;     //链式栈
    stack<int, vector<int>> myVecStack;    //可以任意指定底层的容器

    myStack.push(1);
    myStack.push(2);
    myStack.push(3);
    myStack.push(4);
    myStack.push(5);

    while (!myStack.empty())
    {
        cout << myStack.top() << endl;    //打印栈顶元素
        myStack.pop();

    }

    system("pause");
    return 0;
}

    

  2.7 线性容器 ( queue): 队列

#include <iostream>
#include <queue>    //队列
#include <list>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    queue<int> myQ;                    //queue默认底层是deque实现的
    queue<int, list<int>> myListQ;    //指定底层容器为list
    queue<int, vector<int>> myVecQ;

    myQ.push(1);
    myQ.push(2);
    myQ.push(3);
    myQ.push(4);
    /*
    for (auto i : myQ)        //队列不允许迭代器访问
    {
        cout << i << " ";
    }
    cout << endl;
    */

    while (!myQ.empty())
    {
        cout << myQ.front() << endl;    //打印栈顶元素
        myQ.pop();
    }

    system("pause");
    return 0;
}

    

  2.8 线性容器 ( string ): 字符串

#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;

int main()
{
    string str1 = "1234";
    string str2 = "5678";
    string str3 = str1 + str2;

    str3.push_back('X');
    cout << str3 << endl;

    const char *p = str3.c_str();    //只能用只读指针const char *,返回内部指针
    cout << p << endl;
    cout << *p << endl;

    for (auto i:str3)
    {
        cout << i << " ";
    }
    cout << endl;

    for (auto cb = str3.cbegin(), ce = str3.cend(); cb != ce; cb++)
    {
        cout << *cb << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

    

#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;

int main()
{
    string s1("12345hello hello hahaha");
    s1.insert(s1.begin() + 3, 'X');    //任意位置插入字符
    cout << s1 << endl;

    s1.erase(s1.begin() + 2, s1.begin() + 4);    //删除从s1.begin() + 2到s1.begin() + 4的字符
    cout << s1 << endl;

    s1.erase(1, 2);                               //删除从1开始的2个字符
    cout << s1 << endl;

    s1.replace(0, 2, "world");                    //从0位置开始,替换2个位置,替换内容为world
    cout << s1 << endl;

    s1.replace(s1.begin(), s1.begin()+5, "China");
    cout << s1 << endl;

    s1.replace(5, 0, " haha ");                   //使用replace插入字符串
    cout << s1 << endl;

    cout << s1.find("ha") << endl;                //查找
    cout << s1.find("ha",15) << endl;             //指定位置开始查找

    cout << s1.rfind("ha") << endl;               //反向查找

    cout << s1.find_first_of("1234a") << endl;        //查找第一个属于"1234a"的字符
    cout << s1.find_first_not_of("1234a") << endl;    //第一个不属于的字符

    cout << s1.length() << endl;    //字符串的长度
    cout << s1.size() << endl;      //总共分配的长度

    s1.empty();        //清空
    cout << s1 << endl;
    cout << s1.length() << endl;

    system("pause");
    return 0;
}

    

3. 非线性容器:

  3.1 优先队列( priority_queue ):

#include <iostream>
#include <queue>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    priority_queue<int> myQ;    //优先队列

    myQ.push(11);
    myQ.push(22);
    myQ.push(33);
    myQ.push(44);
    while (!myQ.empty())
    {
        cout << myQ.top() << endl;    //打印栈顶元素
        myQ.pop();
    }

    system("pause");
    return 0;
}

    

#include <iostream>
#include <queue>
#include <list>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;

struct getMoney
{
    char *com;    //公司
    int money;    //工资
};

struct lessX
{
    bool operator ()(struct getMoney &m1, struct getMoney &m2)    //伪函数
    {
        //return m1.money < m2.money;            //按money排序
        if (strcmp(m1.com, m2.com) >= 0)        //按com排序
            return true;
        else
            return false;
    }
};

int main()
{
    priority_queue<getMoney,deque<getMoney>, lessX> myQ;    //优先队列
    getMoney getm[4] = { {"google",30},{"baidu",20},{"360",15},{"tencent",10} };

    for (auto i:getm)
    {
        myQ.push(i);
    }
    while (!myQ.empty())
    {
        cout << myQ.top().com << " " << myQ.top().money << endl;    
        myQ.pop();
    }

    system("pause");
    return 0;
}

    

  3.2 位处理容器( bitset ):

#include <iostream>
#include <bitset>    //处理位运算
#include <string>
using namespace std;

int main()
{
    bitset<8> mybit(205);    //1100 1101        8位

    for (int i = 7; i >= 0; i--)    //C++中 高字节在低位 ==>需要逆序打印
    {
        cout << mybit[i];
        if (i % 4 == 0)        //每4位隔开,便于观察
        {
            cout << " ";
        }
    }
    cout << endl;

    system("pause");
    return 0;
}

    

#include <iostream>
#include <bitset>    //处理位运算
#include <string>
using namespace std;

int main()
{
    char ch = -1;
    bitset<8> mybit(ch);    //8位        
                            //1000 0001    原码
                            //1111 1110    反码
                            //1111 1111 补码

    for (int i = 7; i >= 0; i--)    //C++中 高字节在低位 ==>需要逆序打印
    {
        cout << mybit[i];
        if (i % 4 == 0)        //每4位隔开,便于观察
        {
            cout << " ";
        }
    }
    cout << endl;

    system("pause");
    return 0;
}

    

#include <iostream>
#include <bitset>    //处理位运算
#include <string>
using namespace std;

int main()
{
    float fl = 19.875;
    cout << (void *)&fl << endl;

    //浮点数无法处理,只能处理整数,浮点数会转化为整数
    bitset<32> mybit(fl);    //32位        float占4字节
                            
    for (int i = 31; i >= 0; i--)    //C++中 高字节在低位 ==>需要逆序打印
    {
        cout << mybit[i];
        if (i % 4 == 0)        //每4位隔开,便于观察
        {
            cout << " ";
        }
    }
    cout << endl;

    system("pause");
    return 0;
}

    

   3.3 集合( set ):==>不允许重复的数据

#include <iostream>
#include <set>        //底层是红黑树,自动保证平衡,自动生成平衡查找二叉树
#include <cstdlib>
using namespace std;

int main()
{
    set<int> myset{ 1,2,10,4,6 };    //set是用红黑树(会自动调整为平衡二叉查找树)实现的
    myset.insert(16);
    myset.insert(15);
    myset.insert(15);                //重复数据会被忽略

    myset.erase(10);    //直接删除

    for (auto i:myset)
    {
        cout << i << " ";
    }
    cout << endl;

    for (auto ib = myset.begin(), ie = myset.end(); ib != ie; ib++)
    {
        cout << *ib << " ";
    }
    cout << endl;

    for (auto rb = myset.rbegin(), re = myset.rend(); rb != re; rb++)    //反向迭代器
    {
        cout << *rb << " ";
    }
    cout << endl;

    auto it = myset.find(15);        //查找
    if (it != myset.end())
    {
        cout << "find " << *it << endl;
    }
    else
    {
        cout << "not find" << endl;
    }

    cout << myset.size() << endl;    //元素个数
    myset.empty() ;                  //清空
    
    auto it1 = myset.find(15);       //查找
    if (it1 != myset.end())
    {
        myset.erase(it1);            //根据迭代器获取位置,删除
    }
    for (auto i : myset)
    {
        cout << i << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

    

  实现复杂数据类型自动排序:

#include <iostream>
#include <set>        //底层是红黑树,自动保证平衡,自动生成平衡查找二叉树
#include <cstdlib>
#include <cstring>
using namespace std;

struct strless
{
    bool operator()(const char *str1, const char *str2)    //伪函数
    {
        return (strcmp(str1, str2) < 0);
    }
};

int main()
{
    const char *p[] = { "calc","notepad","run","go","123" };
    set<const char *, strless> myset(p, p + 5, strless());        //实现字符串的自动排序
    myset.insert("245");
    for (auto i:myset)
    {
        cout << i << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

    

  3.4 多集合( multiset ):==>允许有重复数据

#include <iostream>
#include <set>        
#include <cstdlib>
#include <cstring>
using namespace std;

struct strless
{
    bool operator()(const char *str1, const char *str2)    //伪函数
    {
        return (strcmp(str1, str2) < 0);
    }
};

int main()
{
    multiset<int> myset{ 1,2,3,3,3,4,4,5 };    //底层是红黑树,每个元素是一个链表
    myset.insert(101);
    myset.insert(101);
    myset.insert(101);

    for (auto i:myset)
    {
        cout << i << " ";
    }
    cout << endl;

    auto it = myset.equal_range(3);        //返回值是pair类型  pair<链表起点,链表终点>
    //cout << typeid(it).name() << endl;
    for (auto i = it.first; i != it.second; i++)
    {
        cout << *i << " ";
    }
    cout << endl;

    auto it1 = myset.find(101);            //只查找链表的第一个元素
    cout << "find: "<<*it1 << endl;

    /*实现复杂数据类型*/
    const char *p[] = { "calc","notepad","run","go","go","go","123" };
    multiset<const char *, strless> myset1(p, p + 7, strless());        //实现字符串的自动排序
    myset1.insert("245");
    for (auto i : myset1)
    {
        cout << i << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

    

  3.5 哈希表( hash_set ):已被unordered_set 替代

#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS    //现在用新的容器unordered_set取代了hash_set,需要定义这个宏
#include <iostream>
#include <hash_set>    //底层是哈希表,是无序的
#include <cstring>
using namespace std;

struct strless
{
    bool operator()(const char *str1, const char *str2)    const    //伪函数
    {
        return (strcmp(str1, str2) == 0);    //哈希表只能处理相等
    }
};

int main()
{
    //哈希表,不需要考虑碰撞,查询的效率最高
    hash_set<int> myset{ 1,19,2,18,3,17,4,16 };
    myset.insert(29);
    for (auto i:myset)
    {
        cout << i << " ";
    }
    cout << endl;

    for (auto ib = myset.begin(), ie = myset.end(); ib != ie; ib++)
    {
        cout << *ib << " ";
    }
    cout << endl;

    for (auto rb = myset.rbegin(), re = myset.rend(); rb != re; rb++)    //反向迭代器
    {
        cout << *rb << " ";
    }
    cout << endl;

    cout << myset.size() << endl;            //元素个数
    cout << myset.bucket_count() << endl;    //64是哈希表的大小

    /*实现复杂数据类型*/
    hash_set<const char *, hash_compare<const char *, strless>> hs;    //hash_compare<const char *, strless>设定哈希函数,根据实际需求(string)设定哈希函数
    hs.insert("apple");
    hs.insert("google");
    hs.insert("Microsoft");
    hs.insert("oracle");

    auto i = hs.find("google");
    if (i != hs.end())
    {
        cout << "find: " << *i << endl;        //为什么输出apple呢???
    }

    system("pause");
    return 0;
}

    

  3.6 哈希表( unordered_set ):==>不允许重复数据

#include <iostream>
#include <unordered_set>    //凡是带unordered的容器底层都是哈希表实现,而不是红黑树
#include <string>
using namespace std;

int main()
{
    unordered_set<string> myset{ "hello","world","move","jump","abc","last","one","sun","best" };    //unordered_set是无序的,按照哈希函数进行存放
    
    myset.erase(myset.begin());                  //删除哈希表的第一个
    myset.erase("hello");                        //精准删除
    //myset.erase(myset.begin(), myset.end());   //删除某一段

    for (auto i:myset)
    {
        cout << i << " ";
    }
    cout << endl;

    myset.insert("love");    //插入

    for (auto ib = myset.begin(), ie = myset.end(); ib != ie; ib++)
    {
        cout << *ib << " ";
    }
    cout << endl;

    cout << "bucket_count:" << myset.bucket_count() << endl;    //哈希表长度,自动增长,没有规律
    cout << "max_size:" << myset.max_size() << endl;            //最大大小
    cout << "size:" << myset.size() << endl;                    //当前大小

    for (int i = 0; i < myset.bucket_count(); i++)                   //打印整个哈希表(按bucket打印),可见unordered_set不允许重复,
    {                                                                //而unordered_multiset允许重复
        cout << "bucket:" << i << ":  ";
        for (auto it = myset.begin(i); it != myset.end(i); it++)
        {
            cout << " " << *it;
        }
        cout << endl;
    }

    system("pause");
    return 0;
}

    

    

  3.7 哈希表( unordered_multiset ):==>允许重复数据

#include <iostream>
#include <unordered_set>
#include <string>
using namespace std;

int main()
{
    unordered_multiset<string> myset{ "pig","pig","pig","hen" };
    myset.insert("love");    //插入

    for (auto i:myset)
    {
        cout << i << endl;
    }
    cout << "\n";

    auto it = myset.equal_range("pig");
    while (it.first != it.second)        //相同元素在链表上,起点为first,终点为second
    {
        cout << *it.first++ << endl;
    }

    system("pause");
    return 0;
}

    

  3.8 映射( map ) ==> 不允许重复 <==> 红黑树实现

#include <iostream>
#include <map>        //底层是红黑树
#include <cstring>
using namespace std;

//仿函数:STL六大组件之一
struct strless
{
    bool operator()(const char *str1, const char *str2) 
    {
        return (strcmp(str1, str2) < 0);    //字符串对比
    }
};

int main()
{
    map<char *, int> mymap;
    mymap.insert(pair<char *, int>("司令1", 10));
    mymap.insert(pair<char *, int>("司令2", 11));
    mymap.insert(pair<char *, int>("司令3", 13));
    mymap.insert(pair<char *, int>("司令4", 12));
    mymap.insert(pair<char *, int>("司令4", 1211));    //第一个字段,不允许有重复

    for (auto i : mymap)
    {
        cout << i.first << " " << i.second << endl;
    }

    for (auto cb = mymap.cbegin(), ce = mymap.cend(); cb != ce; cb++)
    {
        cout << (*cb).first << " " << (*cb).second << endl;
    }

    auto it = mymap.find("司令2");
    cout << "司令2: " << (*it).second << endl;

    /*map的排序实现*/
    map<char *, int, strless> myMap;    //根据strless仿函数来排序
    myMap.insert(pair<char *, int>("a司令1", 10));
    myMap.insert(pair<char *, int>("c司令2", 11));
    myMap.insert(pair<char *, int>("d司令3", 13));
    myMap.insert(pair<char *, int>("b司令4", 12));

    myMap.erase("b司令4");    //删除

    for (auto i : myMap)
    {
        cout << i.first << " " << i.second << endl;
    }

    auto ite = myMap.find("c司令2");
    myMap.erase(ite,myMap.end());        //删除一段(从ite开始到end())
    for (auto i : myMap)
    {
        cout << i.first << " " << i.second << endl;
    }

    auto it2 = myMap.begin()++;        //红黑树,链式存储
    //auto it2 = myMap.begin() + 3;    //只能++,不能+3

    cout << myMap["a司令1"] << endl;    //可以通过下标[]来访问

    //myMap.clear();    //清空

    system("pause");
    return 0;
}

    

  3.9 多映射( multimap ):==> 允许重复 <==> 红黑树实现

#include <iostream>
#include <map>
#include <cstring>
using namespace std;

struct strless
{
    bool operator()(const char *str1, const char *str2)
    {
        return (strcmp(str1, str2) < 0);    //字符串对比
    }
};

int main()
{
    multimap<char *, int, strless> mymap;    //multimap允许重复    加上strless仿函数后可以进行排序
    mymap.insert(pair<char *, int>("司令1", 10));
    mymap.insert(pair<char *, int>("司令4", 121));
    mymap.insert(pair<char *, int>("司令4", 122));
    mymap.insert(pair<char *, int>("司令2", 11));
    mymap.insert(pair<char *, int>("司令3", 13));
    mymap.insert(pair<char *, int>("司令4", 123));
    mymap.insert(pair<char *, int>("司令4", 124));

    for (auto i : mymap)
    {
        cout << i.first << " " << i.second << endl;
    }
    cout << endl;

    auto it = mymap.equal_range("司令4");
    for (auto ib = it.first, ie = it.second; ib != ie; ib++)
    {
        cout << (*ib).first << " " << (*ib).second << endl;
    }
    cout << endl;

    system("pause");
    return 0;
}

    

  3.10 哈希映射( hash_map ):是unordered_map的前身

#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
#include <iostream>
#include <hash_map>
#include <string>
using namespace std;

//增删查改与map一样,本质是哈希表
int main()
{
    hash_map<string, double> mymap{ { "good",120.32 },{ "better",150.89 },{ "best",218.56 },{ "hello",75.36 },{ "kitty",187.85 } };
    mymap.insert(pair<string, double>("love", 356.71));                    //插入
    mymap.insert(hash_map<string, double>::value_type("like", 289.48));    //插入

    for (auto i : mymap)
    {
        cout << i.first << "   " << i.second << endl;
    }
    cout << endl;

    auto it = mymap.find("hello");        //查找
    if (it != mymap.end())
    {
        cout << it->second << endl;
    }

    /*显示哈希表*/
    for (int i = 0; i < mymap.bucket_count(); i++)                   //打印整个哈希表(按bucket打印),可见unordered_set不允许重复,
    {                                                                //而unordered_multiset允许重复
        cout << "bucket:" << i << ":  ";
        for (auto it = mymap.begin(i); it != mymap.end(i); it++)
        {
            cout << " " << it->first << " " << it->second;
        }
        cout << endl;
    }

    system("pause");
    return 0;
}

    

   3.11 映射( unordered_map ):==> 不允许重复 <==> 哈希表实现

    若要求综合性能,选:map

    若要求最高查询性能,选:unordered_map

#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

//增删查改与map一样,本质是哈希表
int main()
{
    unordered_map<string, double> mymap{ {"good",120.32},{"better",150.89},{"best",218.56},{"hello",75.36},{"kitty",187.85} };
    mymap.insert(pair<string, double>("love", 356.71));                        //插入
    mymap.insert(unordered_map<string, double>::value_type("like",289.48));    //插入

    for (auto i : mymap)
    {
        cout << i.first << "   " << i.second << endl;
    }
    cout << endl;

    auto it = mymap.find("hello");        //查找
    if (it != mymap.end())
    {
        cout << it->second << endl;
    }

    /*显示哈希表*/
    for (int i = 0; i < mymap.bucket_count(); i++)                   //打印整个哈希表(按bucket打印),可见unordered_set不允许重复,
    {                                                                //而unordered_multiset允许重复
        cout << "bucket:" << i << ":  ";
        for (auto it = mymap.begin(i); it != mymap.end(i); it++)
        {
            cout << " " << it->first<<" "<<it->second;
        }
        cout << endl;
    }

    system("pause");
    return 0;
}

    

   3.12 映射( unordered_multimap ):==> 允许重复 <==> 哈希表实现

#include <iostream>
#include <unordered_map>
#include <string>
#include <algorithm>
using namespace std;

//增删查改与map一样,本质是哈希表,允许重复
int main()
{
    unordered_multimap<string, double> mymap{ { "good",120.32 },{ "better",150.89 },{ "best",218.56 } };
    mymap.insert(pair<string, double>("love", 356.71));                            //插入
    mymap.insert(pair<string, double>("love", 218.34));
    mymap.insert(pair<string, double>("love", 568.45));
    mymap.insert(unordered_map<string, double>::value_type("like", 289.48));    //插入

    for (auto i : mymap)
    {
        cout << i.first << "   " << i.second << endl;
    }
    cout << endl;

    auto it = mymap.find("hello");        //查找
    if (it != mymap.end())
    {
        cout << it->second << endl;
    }

    /*显示哈希表*/
    for (int i = 0; i < mymap.bucket_count(); i++)                    //打印整个哈希表(按bucket打印),可见unordered_set不允许重复,
    {                                                                //而unordered_multiset允许重复
        cout << "bucket:" << i << ":  ";
        for (auto it = mymap.begin(i); it != mymap.end(i); it++)
        {
            cout << " " << it->first << " " << it->second;
        }
        cout << endl;
    }
    cout << endl;

    auto itx = mymap.equal_range("love");
    for_each(itx.first, itx.second, [](unordered_multimap<string, double>::value_type &x) {cout << x.first << " " << x.second << endl; });

    system("pause");
    return 0;
}

    

  3.13 用于计算的 valarray:

#include <iostream>
#include <valarray>    //用于计算,计算的性能高于vector,array
#include <iomanip>
using namespace std;

int main()
{
    const double PI = 3.1415926535;
    
    valarray<double> val(9);
    for (int i = 0; i < 9; i++)
    {
        val[i] = PI*i*i;
        cout << val[i] << endl;
    }

    valarray<double> valx(9);
    for (int i = 0; i < 9; i++)
    {
        valx[i] = cos(i*PI / 3);    //可以直接进行科学计算cos()
        cout << valx[i] << endl;
    }

    valarray<char *> my;    //拥有数组的所有功能,长处是计算

    system("pause");
    return 0;
}

    

 4. 容器小结:

 

posted @ 2018-11-23 11:35  博观&约取  阅读(309)  评论(0编辑  收藏  举报