STL容器常用API

 string常用API

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;

//1. 字符串构造
/*
string();//创建一个空的字符串 例如: string str;
string(const string& str);//使用一个string对象初始化另一个string对象
string(const char* s);//使用字符串s初始化
string(int n, char c);//使用n个字符c初始化

*/
void test01(){

    string s1;
    string s2(10, 'a');
    string s3(s2);
    string s4("hello wolrd!");

    cout << s2 << endl;//aaaaaaaaaa
    cout << s3 << endl;//aaaaaaaaaa
    cout << s4 << endl;//hello wolrd!
}

//2. string基本赋值操作
/*
string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
string& operator=(const string &s);//把字符串s赋给当前的字符串
string& operator=(char c);//字符赋值给当前的字符串
string& assign(const char *s);//把字符串s赋给当前的字符串
string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
string& assign(const string &s);//把字符串s赋给当前字符串
string& assign(int n, char c);//用n个字符c赋给当前字符串
string& assign(const string &s, int start, int n);//将s从start开始n个字符赋值给字符串
*/
void test02(){

    string s1;
    s1 = "hello world!";
    cout << s1 << endl;//hello world!

    string s2;
    //s2.assign(s1);
    s2.assign("hello obama!");
    cout << s2 << endl;//hello obama!
}

//3.  string存取字符操作
/*
char& operator[](int n);//通过[]方式取字符
char& at(int n);//通过at方法获取字符
*/
void test03(){
    
    string s = "hello world!";

    for (int i = 0; i < s.size(); i ++){
        cout << s[i] << " ";
    }

    cout << endl;
    for (int i = 0; i < s.size(); i++){
        cout << s.at(i) << " ";
    }
    cout << endl;

    //[]访问越界不抛异常,直接挂掉。at越界了,会抛出异常。

    try{
        //cout << s[100] << endl;
        cout << s.at(100) << endl;
    }
    catch (out_of_range &ex){
        cout << ex.what() << endl;
        cout << "捕获异常!" << endl;
    }

}

//4. string拼接操作
/*
string& operator+=(const string& str);//重载+=操作符
string& operator+=(const char* str);//重载+=操作符
string& operator+=(const char c);//重载+=操作符
string& append(const char *s);//把字符串s连接到当前字符串结尾
string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串结尾
string& append(const string &s);//同operator+=()
string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
string& append(int n, char c);//在当前字符串结尾添加n个字符c
*/
void test04(){

    string s1 = "aaa";
    s1 += "bbb";
    s1 += 'c';
    cout << s1 << endl;

    s1.append("ddddd",3);
    cout << s1 << endl;//aaabbbcddd
    
}

//5. string查找和替换
/*
int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从pos开始查找
int find(const char* s, int pos = 0) const;  //查找s第一次出现位置,从pos开始查找
int find(const char* s, int pos, int n) const;  //从pos位置查找s的前n个字符第一次位置
int find(const char c, int pos = 0) const;  //查找字符c第一次出现位置
int rfind(const string& str, int pos = npos) const;//查找str最后一次位置,从pos开始查找
int rfind(const char* s, int pos = npos) const;//查找s最后一次出现位置,从pos开始查找
int rfind(const char* s, int pos, int n) const;//从pos查找s的前n个字符最后一次位置
int rfind(const char c, int pos = 0) const; //查找字符c最后一次出现位置
string& replace(int pos, int n, const string& str); //替换从pos开始n个字符为字符串str
string& replace(int pos, int n, const char* s); //替换从pos开始的n个字符为字符串s
*/
void test05(){
    string s = "abcdefgd";
    cout << "test05-1:"<< s.find('d') << endl;//4
    cout << "test05-2:"<< s.rfind('d') << endl;//5

    s.replace(2, 3, "AAA");
    cout << "test05-3:"<<s << endl;//abAAAfgd
}

//6. string比较操作
/*
int compare(const string &s) const;//与字符串s比较
int compare(const char *s) const;//与字符串s比较
*/
void test06(){
    string s1 = "hello";
    string s2 = "hello";
    const char *str = "world";

    if (s1.compare(s2) == 0){
        cout << "s1 == s2!" << endl;
    }

    if (s2.compare(str) == 0){
        cout << "s1 == str!" << endl;
    }
}

//7. string子串
/*
string substr(int pos = 0, int n = npos) const;//返回由pos开始的n个字符组成的字符串
*/
void test07(){
    string email = "hello world@gmail.com";
    int pos = email.find('@');
    string username = email.substr(0,pos);
    cout << "test07-1:"<< username << endl;//hello world

    string prex = email.substr(pos + 1);
    cout << "test07-2:"<< prex << endl;//gmail.com
}

//8. string插入和删除操作
/*
string& insert(int pos, const char* s); //插入字符串
string& insert(int pos, const string& str); //插入字符串
string& insert(int pos, int n, char c);//在指定位置插入n个字符c
string& erase(int pos, int n = npos);//删除从Pos开始的n个字符
*/

void test08(){
    string s = "aaaa";
    s.insert(3, "AAAA");
    cout << "test08-1:"<< s << endl;//aaaAAAAa
    s.insert(3, 5, 'M');
    cout << "test08-2:"<< s << endl;//aaaMMMMMAAAAa
    s.erase(2, 3);
    cout << "test08-3:"<< s << endl;//aaMMMAAAAa
}

//9.  string和c-style字符串转换
void test09(){
    
    const char *str = "hello wolrd!";
    //const char * -> string
    string s(str);

    cout << str << endl;

    //string -> const char *
    const char *s2 = s.c_str();
    cout << s2 << endl;

}

//10. 字符串的内存被重新分配之后,可能发生错误.
void test10(){

    //[]和at函数返回都是引用
    string s = "abcde";
    char &a = s[2];
    char &b = s[3];

    a = '1';
    b = '2';

    cout << "a:" << a << endl;
    cout << "b:" << b << endl;
    cout << s << endl;
    cout << "字符串原空间地址:" << (int *)s.c_str() << endl;

    s = "123456789abcdefg";
    cout << "字符串原空间地址:" << (int *)s.c_str() << endl;

    //字符串在字符串操作过程中,可能会导致重新分配内存,之前引用的内存就会失效。
    a = '3';
}

//11. 迭代器遍历字符串
void test11(){

    string s = "hello world!";
    for (string::iterator it = s.begin(); it != s.end(); ++it){
        cout << *it << " ";
    }
    cout << endl;

    for (string::reverse_iterator it = s.rbegin(); it != s.rend(); ++it){
        cout << *it << " ";
    }
    cout << endl;
}
int main(){

    //test01();
    //test02();
    //test03();
    test04();
    //test05();
    //test06();
    test07();
    test08();
    test09();
    //test10();
    //test11();
    return 0;
}

 

vector常用API

1、容器:序列容器(时间决定)、关联式容器(容器中的数据有一定规则)

2、迭代器:通过迭代器寻找、遍历容器中的数据

vetor的使用:数据遍历与输出

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector> //向量 动态数组
#include<algorithm> //算法头文件
#include<string>
using namespace std;

void myPrint(int val){
    cout << val << " ";
}

//1. STL中的容器算法迭代器
void test01(){

    //容器
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40); 
    v.push_back(50);


    //获得开始迭代器
    vector<int>::iterator begin = v.begin();
    //获得结束位置迭代器
    vector<int>::iterator end = v.end();


    //遍历算法
    for_each(begin, end, myPrint);
    cout << endl;
}

//2. 容器可以存放对象
class Person{
    friend ostream& operator<<(ostream& out, Person &person);
public:
    Person(string name,int age){
        this->mName = name;
        this->mAge = age;
    }
public:
    string mName;
    int mAge;
};

ostream& operator<<(ostream& out, Person &person){
    out << "Name:" << person.mName << " Age:" << person.mAge << endl;
    return out;
}
void test02(){
    
    vector<Person> v;
    //在向容器中插入元素的时候,一定要保证元素能够被拷贝。
    v.push_back(Person("aaa", 10));
    v.push_back(Person("bbb", 20));
    v.push_back(Person("ccc", 30));
    v.push_back(Person("ddd", 40));
    v.push_back(Person("eee", 50));


    vector<Person>::iterator begin = v.begin();
    vector<Person>::iterator end = v.end();

    while (begin != end){
        cout << (*begin);
        ++begin;
    }
}

//3. 存放对象指针
void test03(){
    
    vector<Person *> v;

    //创建数据
    Person *p1 = new Person("aaa", 10);
    Person *p2 = new Person("bbb", 20);
    Person *p3 = new Person("ccc", 30);
    Person *p4 = new Person("ddd", 40);
    Person *p5 = new Person("eee", 50);

    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    v.push_back(p5);


    vector<Person *>::iterator begin = v.begin();
    vector<Person *>::iterator end = v.end();

    while (begin != end){
        cout << (*begin)->mName << " " << (*begin)->mAge << endl;
        ++begin;
    }

    delete p5;
    delete p4;
    delete p3;
    delete p2;
    delete p1;

}


//4. 容器可以嵌套容器
void test04(){
    
    vector<vector<int>> vs;

    vector<int> v1;
    vector<int> v2;
    vector<int> v3;
    vector<int> v4;
    vector<int> v5;

    for (int i = 0; i < 5;i ++){
        v1.push_back(i + 10);
        v2.push_back(i + 20);
        v3.push_back(i + 30);
        v4.push_back(i + 40);
        v5.push_back(i + 50);
    }

    vs.push_back(v1);
    vs.push_back(v2);
    vs.push_back(v3);
    vs.push_back(v4);
    vs.push_back(v5);

    vector<vector<int>>::iterator begin = vs.begin();
    vector<vector<int>>::iterator end = vs.end();

    while (begin != end){
        
        vector<int>::iterator sbegin = (*begin).begin();
        vector<int>::iterator send = (*begin).end();

        while (sbegin != send){
            cout << *sbegin << " ";
            ++sbegin;
        }
        cout << endl;

        ++begin;
    }

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

    for (vector<vector<int>>::iterator it = vs.begin(); it != vs.end(); ++it){
        for (vector<int>::iterator sit = it->begin(); sit != it->end(); ++sit){
            cout << *sit << " ";
        }
        cout << endl;
    }

}


int main(){

    //test01();
    //test02();
    //test03();
    test04();


    system("pause");
    return EXIT_SUCCESS;
}

 Vector常用API

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
using namespace std;

void printVector(const vector<int> &vec){
    for (vector<int>::const_iterator it = vec.begin(); it != vec.end(); ++it){
        cout << *it << " ";
    }
    cout << endl;
}

void printReverseVector(vector<int> &vec){
    for (vector<int>::reverse_iterator it = vec.rbegin(); it != vec.rend(); ++it){
        cout << *it << " ";
    }
    cout << endl;
}


//1. vector构造
/*
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end());//将v[begin(), end())区间中的元素拷贝给本身。
vector(n, elem);//构造函数将n个elem拷贝给本身。
vector(const vector &vec);//拷贝构造函数。

//例子 使用第二个构造函数 我们可以...
int arr[] = {2,3,4,1,9};
vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
*/
void test01(){

    int arr[] = { 2, 3, 4, 1, 9 };
    vector<int> v(arr,arr+ sizeof(arr)/sizeof(int));

    printVector(v);
    printReverseVector(v);

    vector<int> v2(10, 6);
    printVector(v2);
}

//2. vector常用赋值操作
/*
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
vector& operator=(const vector  &vec);//重载等号操作符
swap(vec);// 将vec与本身的元素互换。
*/
void test02(){
    vector<int> v;
    v.assign(10, 6);

    
    vector<int> v2;
    v2.push_back(1);
    v2.push_back(2);
    v2.push_back(3);

    printVector(v);
    printVector(v2);

    cout << "-----------------" << endl;
    v.swap(v2);
    printVector(v);
    printVector(v2);

    //v.assign(v2.begin(),v2.end());
    //printVector(v);
}

//3. 大小操作
/*
size();//返回容器中元素的个数
empty();//判断容器是否为空
resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长>度的元素被删除。
capacity();//容器的容量
reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。
*/

void test03(){

    //1. resize开辟空间,并且初始化
    //2. reserve只开辟空间,没有初始化
    vector<int> v2;
    v2.push_back(1);
    v2.push_back(2);
    v2.push_back(3);

    cout << "size:" << v2.size() << endl;
    v2.resize(5); //改变容器中元素的个数,多余的扔掉
    cout << "size:" << v2.size() << endl;
    printVector(v2);

    v2.reserve(20); //预留空间
    v2.push_back(10);
    printVector(v2);
    cout << "size:" << v2.size() << endl;
}

void test04(){

    vector<int> v;
    v.resize(5);
    v.push_back(10);
    cout << "capacity:" << v.capacity() << endl;
    cout << "size:" << v.size() << endl;

    cout << "----------" << endl;
    vector<int> v2;
    v2.reserve(5);
    v2.push_back(10);
    cout << "capacity:" << v2.capacity() << endl;
    cout << "size:" << v2.size() << endl;

    //cout << v2[2] << endl;
}

void test05(){
    
    vector<int> v;

    v.reserve(100000);

    int *p = NULL;
    int count = 0;
    for (int i = 0; i < 100000;i ++){
        v.push_back(i);
        if (p != &v[0]){
            p = &v[0];
            count++;
        }
    }
    cout << count << endl;
}

//swap用法
void test06(){

    vector<int> v;
    for (int i = 0; i < 100000; i++){
        v.push_back(i);
    }

    cout << "容量:" << v.capacity() << endl;
    cout << "大小:" << v.size() << endl;

    cout << "---------------" << endl;
    v.resize(10);
    cout << "容量:" << v.capacity() << endl;
    cout << "大小:" << v.size() << endl;

    cout << "---------------" << endl;
    vector<int>(v).swap(v);
    cout << "容量:" << v.capacity() << endl;
    cout << "大小:" << v.size() << endl;
}


//7. vector数据存取操作
/*
at(int idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
operator[];//返回索引idx所指的数据,越界时,运行直接报错
front();//返回容器中第一个数据元素
back();//返回容器中最后一个数据元素
*/
void test07(){


    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    cout << v.front() << endl;
    cout << v.back() << endl;

    v.front() = 100;
    v.back() = 200;

    for (int i = 0; i < v.size(); i ++){
        cout << v[i] << " ";
    }
    cout << endl;
}

//8. vector插入删除
/*
insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元素ele.
push_back(ele); //尾部插入元素ele
pop_back();//删除最后一个元素
erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素
erase(const_iterator pos);//删除迭代器指向的元素
clear();//删除容器中所有元素
*/
void test08(){
    
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);

    v.insert(v.begin()+2,100);
    printVector(v);

    v.pop_back();
    printVector(v);
    v.erase(v.begin());
    printVector(v);
    v.erase(v.begin(),v.end());
    cout << "size:" << v.size() << endl;

}


int main(){

    //test01();
    //test02();
    //test03();
    //test04();
    //test05();
    //test06();
    //test07();
    test08();

    system("pause");
    return EXIT_SUCCESS;
}

 

deque

分块储存数据,双口分段式连续内存空间容器,无大小和容量概念

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<deque>
#include<vector>
#include<ctime>
#include<algorithm>
#include<string>
using namespace std;

void printDeque(const deque<int> &d){
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); ++it){
        cout << *it << " ";
    }

    //deque<int>::reverse_iterator

    cout << endl;
}

//1. deque构造函数
/*
deque<T> deqT;//默认构造形式
deque(beg, end);//构造函数将[beg, end)区间中的元素拷贝给本身。
deque(n, elem);//构造函数将n个elem拷贝给本身。
deque(const deque &deq);//拷贝构造函数。

*/
void test01(){

    int arr[] = { 1, 2, 3, 4, 5, 6 };
    deque<int> d1(arr,arr+sizeof(arr)/sizeof(int));
    printDeque(d1);

    deque<int> d2(10, 6);
    printDeque(d2);

}

//2.deque赋值操作 
/*
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
deque& operator=(const deque &deq); //重载等号操作符
swap(deq);// 将deq与本身的元素互换

*/
void test02(){

    int arr[] = { 1, 2, 3, 4, 5, 6 };
    deque<int> d1(arr, arr + sizeof(arr) / sizeof(int));
    printDeque(d1);

    deque<int> d2;
    d2.assign(d1.begin(),d1.end());
    d2.push_back(100);
    printDeque(d2);

    cout << "--------------" << endl;
    d1.swap(d2);
    printDeque(d1);
    printDeque(d2);
}

//3. deque大小操作
/*
deque.size();//返回容器中元素的个数
deque.empty();//判断容器是否为空
deque.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
*/
void test03(){
    
    deque<int> d;
    cout << d.size() << endl;

    if (d.empty()){
        cout << "空!" << endl;
    }

    d.resize(10, 7);
    printDeque(d);
}

//4. deque双端插入和删除操作
/*
push_back(elem);//在容器尾部添加一个数据
push_front(elem);//在容器头部插入一个数据
pop_back();//删除容器最后一个数据
pop_front();//删除容器第一个数据
*/
void test04(){

    deque<int> d;
    d.push_back(10);
    d.push_front(20);
    printDeque(d);
    d.pop_back();
    d.pop_front();
    cout << d.size() << endl;
}

//5. deque插入操作
/*
insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
*/
void test05(){

    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_back(30);
    d.push_back(40);
    d.push_back(50);

    d.insert(d.begin() + 1,100);
    d.insert(d.begin() + 2, 2, 0);
    printDeque(d);

    deque<int> d2;
    d2.push_back(100);
    d2.push_back(200);
    d2.push_back(300);

    d2.insert(d2.begin() + 1, d.begin() + 1, d.end());
    printDeque(d2);

}

//6. deque删除操作
/*
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
*/
void test06(){

    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_back(30);
    d.push_back(40);
    d.push_back(50);

    d.erase(d.begin());
    d.erase(d.begin(), d.end()); //d.clear();

    cout << d.size() << endl;

}

//学生打分案例
//有5个学生,10个评委分别对这5个学生进行打分,去除最低分,去除最高分,取平均分

class Student{
public:
    string mName;
    int mScore;
};

//创建学生
void CreateStudents(vector<Student> &vec){
    
    string seedName = "ABCDE";
    for (int i = 0; i < 5;i ++){
        
        //创建学生
        Student stu;
        stu.mName = "学生";
        stu.mName += seedName[i];
        stu.mScore = 0;
        //保存学生信息
        vec.push_back(stu);
    }

}

//对每一个学生进行打分
void SetSocre(vector<Student> &vec){

    //种下种子
    srand((unsigned int)time(NULL));

    //遍历学生
    for (vector<Student>::iterator it = vec.begin(); it != vec.end(); ++it){
    
        //保存分数
        deque<int> dScore;
        for (int i = 0; i < 10;i ++){
            int score = rand() % 70 + 30;
            dScore.push_back(score);
        }

        //排序
        sort(dScore.begin(), dScore.end());
        //去除最高分,去除最低分
        dScore.pop_back();
        dScore.pop_front();
        //求总分
        int totalScore = 0;
        for (deque<int>::iterator sit = dScore.begin(); sit != dScore.end();++sit){
            totalScore += (*sit);
        }
        //求平均分
        int avgScore = totalScore / dScore.size();
        //保存当前学生分数
        it->mScore = avgScore;
    }

}
//给学生排序,并且输出
bool mycomapre(Student &s1,Student &s2){
    return s1.mScore > s2.mScore;
}
void ShowStudengsByScore(vector<Student> &vec){
    sort(vec.begin(), vec.end(), mycomapre);
    //学生成绩从大到小显示
    for (vector<Student>::iterator it = vec.begin(); it != vec.end(); ++it){
        cout << "Name:" << it->mName << " Score:" << it->mScore << endl;
    }
}

void test07(){

    vector<Student> vStus; //保存学生信息
    //1.创建学生
    CreateStudents(vStus);
    //2.评委给学生打分
    SetSocre(vStus);
    //3.根据成绩降序排列学生
    ShowStudengsByScore(vStus);
}

int main(){

    //test01();
    //test02();
    //test03();
    //test04();
    //test05();
    //test06();
    test07();

    system("pause");
    return EXIT_SUCCESS;
}

 

list容器

链表容器,不支持随机遍历。不能用通用的sort算法(要有随机访问迭代器),容器自己有排序算法

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

void printList(const list<int> &mylist){

    for (list<int>::const_iterator it = mylist.begin(); it != mylist.end(); ++it){
        cout << *it << " ";
    }
    cout << endl;
}    


//1. list构造函数
/*
list<T> lstT;//list采用采用模板类实现,对象的默认构造形式:
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem);//构造函数将n个elem拷贝给本身。
list(const list &lst);//拷贝构造函数。
*/
void test01(){
    
    //list迭代器是双向迭代器,
    list<int> mylist(10, 1);
    list<int> mylist2(mylist.begin(), mylist.end());
    printList(mylist);

    list<int>::iterator it;
    //sort(mylist.begin(), mylist.end()); //sort算法不能对list容器排序
    mylist.sort();
}

//2. list数据元素插入和删除操作
/*
push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
remove(elem);//删除容器中所有与elem值匹配的元素。
*/

bool mycompare(int val){
    return val > 50;
}


void test02(){
    
    list<int> mylist;
    mylist.push_back(10);
    mylist.push_back(20);
    mylist.push_back(30);
    mylist.push_back(40);
    mylist.push_back(50);
    mylist.push_front(100);
    mylist.push_front(200);
    mylist.push_front(300);
    mylist.push_front(400);

    vector<int> v;
    v.push_back(1000);
    v.push_back(2000);

    mylist.insert(++mylist.begin(), v.begin(), v.end());

    printList(mylist);
    mylist.push_back(300);
    mylist.push_back(300);

    printList(mylist);

    //mylist.remove(300);
    mylist.remove_if(mycompare);

    printList(mylist);

}

//3.  list赋值操作 list数据的存取
/* 
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem);//将n个elem拷贝赋值给本身。
list& operator=(const list &lst);//重载等号操作符
swap(lst);//将lst与本身的元素互换。
front();//返回第一个元素。
back();//返回最后一个元素。


*/

void test03(){
    
    list<int> mylist;
    mylist.assign(10,10);
    printList(mylist);

    cout << mylist.front() << endl;
    cout << mylist.back() << endl;

}

//4. list反转排序
/*
reverse();//反转链表,比如lst包含1,3,5元素,运行此方法后,lst就包含5,3,1元素。
sort(); //list排序
*/

bool canbucanswap(int v1,int v2){
    return v1 > v2;
}
void test04(){

    list<int> mylist;
    mylist.push_back(10);
    mylist.push_back(40);
    mylist.push_back(30);
    mylist.push_back(50);
    mylist.push_back(20);

    printList(mylist);
    mylist.reverse();
    printList(mylist);

    //排序
    mylist.sort(canbucanswap);
    printList(mylist);
}

//list容器迭代器类型要清楚,还要直到list容器是自己提供排序算法,通用的sort算法不能对list排序

int main(){

    //test01();
    //test02();
    //test03();
    test04();

    system("pause");
    return EXIT_SUCCESS;
}

 

set容器

容器内部将数据自动排序(平衡二叉树),不能插入重复元素。multiset可以插入重复元素。不能修改容器中的值,通过删除值,在插入。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<set>
#include<string>
#include<algorithm>
using namespace std;

struct MyComapre{
    bool operator()(int v1, int v2){
        return v1 > v2;
    }
};

void printMySet(set<int, MyComapre> &s){

    for (set<int, MyComapre>::iterator it = s.begin(); it != s.end(); ++it){
        cout << *it << " ";
    }
    cout << endl;
}

//1. 
/*
set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数:
set(const set &st);//拷贝构造函数

insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素。

*/


void test01(){
    
    set<int, MyComapre> s;
    s.insert(4);
    pair<set<int, MyComapre>::iterator, bool> ret = s.insert(2);
    if (ret.second){
        cout << "第一次插入成功!" << endl;
    }
    else{
        cout << "第一次插入失败!" << endl;
    }
    s.insert(3);
    s.insert(9);
    s.insert(6);

    ret = s.insert(2);
    if (ret.second){
        cout << "第一次插入成功!" << endl;
    }
    else{
        cout << "第一次插入失败!" << endl;
    }

    //删除第一个元素的
    s.erase(2);
    s.erase(s.begin());
    //set容器迭代器什么类型?双向迭代器

    printMySet(s);
}

void print(const int &val){
    cout << val << " ";
}

void test02(){
    
    multiset<int> ms;
    ms.insert(7);
    ms.insert(4);
    ms.insert(9);
    ms.insert(2);
    ms.insert(10);
    ms.insert(2);

    for_each(ms.begin(), ms.end(), print);
    cout << endl;
}

//3. set查找操作
/*
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//查找键key的元素个数
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。
*/

void test03(){
    
    set<int> s;
    s.insert(1);
    s.insert(2);
    //s.insert(3);
    s.insert(4);
    s.insert(5);

    set<int>::iterator it = s.find(12);
    if (it == s.end()){
        cout << "查找失败!" << endl;
    }
    else{
        cout << "查找到的值是:" << *it << endl;
    }

    cout << "值为2的元素有:" << s.count(12) << "个!" << endl;

    //lower_bound  upper_bound
    it =  s.lower_bound(2);
    if (it == s.end()){
        cout << "查找失败!" << endl;
    }
    else{
        cout << "查找到的值是:" << *it << endl;
    }

    it = s.upper_bound(2);
    if (it == s.end()){
        cout << "查找失败!" << endl;
    }
    else{
        cout << "查找到的值是:" << *it << endl;
    }
    cout << "------------------------" << endl;

    pair<set<int>::iterator, set<int>::iterator> ret = s.equal_range(2);
    cout << *(ret.first) << endl;
    cout << *(ret.second) << endl;

}

//自定义数据类型
class Person{
public:
    Person(string name,int age){
        this->mName = name;
        this->mAge = age;
    }
public:
    string mName;
    int mAge;
};

struct PersonRule{
    bool operator()(const Person &p1,const Person &p2){
        return p1.mAge > p2.mAge;
    }
};

void test04(){

    set<Person, PersonRule> s;

    s.insert(Person("aaa", 10));
    s.insert(Person("bbb", 70));
    s.insert(Person("ccc", 50));
    s.insert(Person("ddd", 30));
    s.insert(Person("eee", 40));

    for (set<Person, PersonRule>::iterator it = s.begin(); it != s.end();++it){
        cout << "Name:" << it->mName << " Age:" << it->mAge << endl;
    }


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

    //!PersonRule()(p1, p2) && !PersonRule()(p2, p1)

    set<Person, PersonRule>::iterator it =  s.find(Person("aaa", 20));
    if (it == s.end()){
        cout << "查找失败!" << endl;
    }
    else{
        cout << "Name:" << it->mName << " Age:" << it->mAge << endl;
    }

}

int main(){

    //test01();
    //test02();
    //test03();
    test04();


    system("pause");
    return EXIT_SUCCESS;
}

 

map容器

键值和实值是分开的,排序规则按照键值排序

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<map>
#include<string>
using namespace std;

template<class T>
void printMap(T &m){
    for (map<int, string>::iterator it = m.begin(); it != m.end(); ++it){
        cout << "key:" << it->first << " value:" << it->second << endl;
    }
}

//注意:map的排序规则,传入的参数不是pair类型,而是key类型
struct mycompare{
    bool operator()(int key1, int key2){
        return key1 > key2;
    }
};

//1. map容器的使用
void test01(){
    //map是否支持随机访问?不支持随机访问,双向迭代器

    //创建map容器
    map<int, string, mycompare> mymap;

    //1. 第一种插入方式
    mymap.insert(pair<int,string>(3,"aaa"));
    //2. 第二种插入方式
    mymap.insert(make_pair(6, "bbb"));
    //3. 第三种插入方式
    mymap.insert(map<int,string>::value_type(2,"ccc"));
    //4. 第四种插入方式
    mymap[4] = "ddd";
    mymap[4] = "eee";

    mymap.erase(2);

    printMap(mymap);

    //cout << "size:" << mymap.size() << endl;
    //如果使用[]号这种方式输出一个不存在的key的值,那么编译器会以指定key增加新的数据
    //如果使用[]号方式插入一条key存在的数据,那么已有数据会被修改
    //cout << mymap[100] << endl;
    //cout << "size:" << mymap.size() << endl;
}

//3. map查找操作
/*
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;/若不存在,返回map.end();
count(keyElem);//返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对multimap来说,值可能大于1。
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。
*/

void test02(){

    map<int, string> mymap;
    mymap.insert(make_pair(1, "aaa"));
    mymap.insert(make_pair(2, "bbb"));
    mymap.insert(make_pair(3, "ccc"));
    mymap.insert(make_pair(4, "ddd"));
    mymap.insert(make_pair(5, "eee"));

    map<int, string>::iterator it = mymap.find(30);
    if (it == mymap.end()){
        cout << "查找失败!" << endl;
    }
    else{
        cout << "Key:" << it->first << " Value:" << it->second << endl;
    }


    it = mymap.lower_bound(3);
    if (it == mymap.end()){
        cout << "查找失败!" << endl;
    }
    else{
        cout << "Key:" << it->first << " Value:" << it->second << endl;
    }

    it = mymap.upper_bound(3);
    if (it == mymap.end()){
        cout << "查找失败!" << endl;
    }
    else{
        cout << "Key:" << it->first << " Value:" << it->second << endl;
    }

    pair<map<int, string>::iterator, map<int, string>::iterator> ret =  mymap.equal_range(3);
    if (ret.first != mymap.end()){
        cout << "Key:" << ret.first->first << " Value:" << ret.first->second << endl;
    }
    if (ret.second != mymap.end()){
        cout << "Key:" << ret.second->first << " Value:" << ret.second->second << endl;
    }



}

int main(){

    //test01();
    test02();

    system("pause");
    return EXIT_SUCCESS;
}

 

map容器案例:员工分组案例

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<ctime>
using namespace std;

//公司今天招聘了5个员工,5名员工进入公司之后,需要指派员工在那个部门工作
//人员信息有: 姓名 年龄 电话 工资等组成
//通过Multimap进行信息的插入 保存 显示
//分部门显示员工信息 显示全部员工信息

#define SALE_DEPATMENT 1 //销售部门
#define DEVELOP_DEPATMENT 2 //研发部门
#define FINACIAL_DEPATMENT 3 //财务部门

class Woker{
public:
    string mName;
    int mAge;
    int mSalary;
};

//创建员工
void CreateWorkers(vector<Woker> &vWorkers){

    srand((unsigned int)time(NULL));

    string nameSeed = "ABCDE";
    for (int i = 0; i < 5;i ++){
        Woker worker;
        worker.mName = "员工";
        worker.mName += nameSeed[i];
        worker.mAge = rand() % 30 + 30;
        worker.mSalary = rand() % 10000 + 10000;
        vWorkers.push_back(worker);
    }

}
//员工分组
void WokerByGroup(vector<Woker> &vWorkers, multimap<int, Woker>  &mWokers){

    //遍历员工
    for (vector<Woker>::iterator it = vWorkers.begin(); it != vWorkers.end(); ++it){
        
        int departmentID = rand() % 3 + 1;
        //员工保存在分组之后容器中
        mWokers.insert(make_pair(departmentID,*it));
    }

}

void Group(multimap<int, Woker>  &mWokers, int depID){

    multimap<int, Woker>::iterator  it = mWokers.find(depID);
    int mcount = mWokers.count(depID);
    int index = 0;
    for (; it != mWokers.end() && index < mcount; ++it, ++index){
        cout << "Name:" << it->second.mName << " Age:" << it->second.mAge << " Salary:" << it->second.mSalary << "美刀!" << endl;
    }
}
//打印各组员工信息
void PrintWorkers(multimap<int, Woker>  &mWokers){

    cout << "财务部门员工信息如下:" << endl;
    Group(mWokers, FINACIAL_DEPATMENT);
    cout << "研发部门员工信息如下:" << endl;
    Group(mWokers, DEVELOP_DEPATMENT);
    cout << "销售部门员工信息如下:" << endl;
    Group(mWokers, SALE_DEPATMENT);
}




int main(){

    vector<Woker> vWorkers;// 保存未分组的员工信息
    multimap<int, Woker>  mWokers; //保存分组后的员工信息

    CreateWorkers(vWorkers);
    WokerByGroup(vWorkers, mWokers);
    PrintWorkers(mWokers);

    system("pause");
    return EXIT_SUCCESS;
}

模版、类型转换

1、模版函数与普通函数调用规则:数据类型都匹配时:优先调用普通函数、有类型转换。模版函数能产生跟好的匹配,优先调用模版函数。如果运用<>,优先调用模版函数。

2、函数模版通过类型,产生不同的函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

template<class T>
T MyPlus(T a, T b){
    T ret = a + b;
    return ret;
}

int MyPlus(int a, int b){
    int ret = a + b;
    return ret;
}

template<class T>
T MyPlus(T a, T b, T c){
    T ret = a + b;
    return ret;
}


int MyPlus(int a, int b);
void test01(){

    int a = 10;
    char b = 'a';
    //1. 如果函数模板和普通函数都能匹配调用,那么优先调用普通函数
    MyPlus(a, a);
    //2. 如果函数模板能够产生更好的匹配,会调用函数模板

    //3. 就想调用普通函数

    MyPlus<>(a, a);

    //4. 函数模板也可以重载
}

int main(){

    test01();

    system("pause");
    return EXIT_SUCCESS;
}

 

2、类模版

类模版做函数参数:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;

template<class NameType,class AgeType>
class Person{
public:
    Person(NameType name, AgeType age){
        this->mName = name;
        this->mAge = age;
    }
public:
    NameType mName;
    AgeType mAge;
};


#if 0
template<class T>
void printPerson(T &person){
    //cout << typeid(T).name() << endl;
    cout << "Name:" << person.mName << " Age:" << person.mAge << endl;
}
#endif

template<class T1,class T2>
void printPerson(Person<T1,T2> &person){
    cout << "T1 type:" << typeid(T1).name() << endl;
    cout << "T2 type:" << typeid(T2).name() << endl;


    cout << "Name:" << person.mName << " Age:" << person.mAge << endl;
}


void  test(){

    Person<string, int> person("Obama", 20);
    printPerson(person);
}



int main(){

    test();

    system("pause");
    return EXIT_SUCCESS;
}

类模版碰到友元问题

 

posted @ 2017-05-02 15:47  天码丶行满  阅读(273)  评论(0编辑  收藏  举报