QT学习C++(17)

STL概述  标准模板库

STL广义的三大组件 :容器、算法、迭代器

STL六大组件:容器、算法、迭代器、仿函数、适配器、空间配置器

 算法

 迭代器

迭代器的案例:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    //单端动态数组 类模板
    vector<int> v; //v是一个具体的vector容器
    //push_back 尾部插入
    v.push_back(1);
    v.push_back(11);
    v.push_back(111);

    //访问数据
    //定义一个迭代器 存储v的起始迭代器
    vector<int>::iterator B_v = v.begin();
    //定义一个迭代器 存储v的结束迭代器
    vector<int>::iterator E_v = v.end();

    //for循环遍历方式1
    for(; B_v != E_v; B_v++){
        //对迭代器取*代表容器元素
        cout << *B_v << endl;
    }
    cout << endl;
    //for循环遍历方式2 (推荐)
    for(vector<int>::iterator p = v.begin(); p != v.end(); p++){
        cout << *p << endl;
    }
    return 0;
}

 

案例 for_each

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void fun(int v){
    cout << v << " ";
}

int main()
{
    //单端动态数组 类模板
    vector<int> v; //v是一个具体的vector容器
    //push_back 尾部插入
    v.push_back(1);
    v.push_back(11);
    v.push_back(111);

    //访问数据
    //定义一个迭代器 存储v的起始迭代器
    vector<int>::iterator B_v = v.begin();
    //定义一个迭代器 存储v的结束迭代器
    vector<int>::iterator E_v = v.end();

    //for循环遍历方式1
    for(; B_v != E_v; B_v++){
        //对迭代器取*代表容器元素
        cout << *B_v << endl;
    }
    cout << endl;
    //for循环遍历方式2 (推荐)
    for(vector<int>::iterator p = v.begin(); p != v.end(); p++){
        cout << *p << endl;
    }
    cout << endl;
    //STL提供的算法遍历  #include <algorithm>
    //for_each 从容器的起始到结束 逐个元素取出并通过函数fun
    for_each(v.begin(), v.end(), fun);
    cout << endl;
    return 0;
}

 

 案例:容器存放自定义数据类型

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Person{
public:
    string name;
    int age;
    Person(string name, int age): name(name), age(age){}
};

void fun(Person v){
    cout << "name:" << v.name << " age:" << v.age << endl;
}

int main()
{
    Person ob1("lucy1", 18);
    Person ob2("lucy2", 28);
    Person ob3("lucy3", 38);
    //单端动态数组 类模板
    vector<Person> v; //v是一个具体的vector容器
    //push_back 尾部插入
    v.push_back(ob1);
    v.push_back(ob2);
    v.push_back(ob3);

    //STL提供的算法遍历  #include <algorithm>
    //for_each 从容器的起始到结束 逐个元素取出并通过函数fun
    for_each(v.begin(), v.end(), fun);
    cout << endl;
    return 0;
}

容器嵌套容器 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
void fun0(int in_vv);

void fun(vector<int> v){
    for_each(v.begin(), v.end(),fun0);
    cout << endl;
}
void fun0(int in_vv){
    cout << in_vv << " ";
}
int main()
{
    //单端动态数组 类模板
    vector<int> v1; //v是一个具体的vector容器
    vector<int> v2;
    vector<int> v3;
    //push_back 尾部插入
    v1.push_back(1);
    v1.push_back(11);
    v1.push_back(111);

    v2.push_back(2);
    v2.push_back(22);
    v2.push_back(222);

    v3.push_back(3);
    v3.push_back(33);
    v3.push_back(333);
    //定义一个容器v,存放v1,v2,v3
    vector<vector<int>> v;
    v.push_back(v1);
    v.push_back(v2);
    v.push_back(v3);
    //for循环遍历
    cout << "for循环遍历" << endl;
    for(vector<vector<int>>::iterator p = v.begin(); p != v.end(); p++){
        for(vector<int>::iterator in_p = (*p).begin(); in_p != (*p).end(); in_p++){
            cout << *in_p << " ";
        }
        cout << endl;
    }

    //STL提供的算法遍历  #include <algorithm>
    cout << "STL循环遍历" << endl;
    //for_each 从容器的起始到结束 逐个元素取出并通过函数fun
    for_each(v.begin(), v.end(), fun);
    cout << endl;
    return 0;
}

常用容器

string容器

 

vector容器  单端动态数组 

 

 容量>=元素的个数 原因:vector的未雨绸缪机制

vector另寻地址次数

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    int *p = NULL;
    int count = 0;
    for(int i=0; i<50; i++){
        v.push_back(i);
        if(p != &v[0]){
            count ++;
            p = &v[0];
        }
    }

    cout << "另寻地址次数:" << count << endl;
    return 0;
}

 空间满后就需要另寻空间储存

vector的未雨绸缪机制

 reserve空间预留

 

vector的常用操作

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(11);
    v.push_back(111);

    //vector 的存取
    //重载[]
    cout << "重载[]" << endl;
    cout << "v[0]: " << v[0] << ", v[1]: " << v[1] << ", v[2]: " << v[2] << endl;
    // at下标
    cout << ".at()" << endl;
    cout << "v.at(0): " << v.at(0) << ", v.at(1): " << v.at(1) << ", v.at(2): " << v.at(2) << endl;
    cout << endl;
    /*[]和at的区别在于:
      []:发生越界时不抛出异常
      at:发生越界时抛出异常
    */
    //front()和back()
    cout << "front()和back()" << endl;
    cout << "v.front(): " << v.front() << endl;
    cout << "v.back(): " << v.back() << endl;
    cout << endl;
    //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(); //删除容器中所有元素
    */
    cout << "vector的插入和删除" << endl;
    v.insert(v.begin()+1, 3, 0);
    cout << "v.insert: ";
    for(vector<int>::iterator p=v.begin(); p != v.end(); p++){
        cout << *p << " ";
    }
    cout << endl;

    cout << "pop_back: ";
    v.pop_back();
    for(vector<int>::iterator p=v.begin(); p != v.end(); p++){
        cout << *p << " ";
    }
    cout << endl;

    cout << "erase(v.begin()+1, v.end()-2): ";
    v.erase(v.begin()+1, v.end()-2);
    for(vector<int>::iterator p=v.begin(); p != v.end(); p++){
        cout << *p << " ";
    }
    cout << endl;

    cout << "erase(v.begin()+1): ";
    v.erase(v.begin()+1);
    for(vector<int>::iterator p=v.begin(); p != v.end(); p++){
        cout << *p << " ";
    }
    cout << endl;

    cout << "clear(): ";
    v.clear();
    for(vector<int>::iterator p=v.begin(); p != v.end(); p++){
        cout << *p << " ";
    }
    cout << endl;


    return 0;
}

deque容器  双端动态数组

 

 API(接口)

 

#include <iostream>
#include <deque>
#include <algorithm>

using namespace std;

void PrintMem(int p){
    cout << p << " ";
}

int main()
{
    /*deque
     ##deque构造函数
     deque<T> deqT; //默认构造形式
     deque(beg, end); //构造函数将[beg, end)区间中的元素拷贝给本身
     deque(n, elem); //构造函数将n个elem拷贝给本身
     deque(const deque &deq); //拷贝构造函数
     ##deque赋值操作
     assign(beg, end); //将[beg, end)区间中的数据拷贝给赋值本身
     assign(n, elem); //将n个elem拷贝赋值给本身
     deque& operator=(const deque &deq); //重载等号操作符
     swap(deq); //将aeq与本身的元素互换
    */
    deque<int> v0;
    cout << "deque构造函数与赋值" << endl;
    v0.assign(5, 2);
    cout << "v0.assign(5, 2): ";
    for_each(v0.begin(), v0.end(), PrintMem);
    cout << endl;

    deque<int> v1(v0.begin()+1, v0.end()-1);
    cout << "deque v1(v0.begin()+1, v0.end()-1): ";
    for_each(v1.begin(), v1.end(), PrintMem);
    cout << endl;

    deque<int> v2(5, 1);
    cout << "deque v2(5, 1): ";
    for_each(v2.begin(), v2.end(), PrintMem);
    cout << endl;

    deque<int> v3(v2);
    cout << "v3(v2): ";
    for_each(v3.begin(), v3.end(), PrintMem);
    cout << endl;

    deque<int> v4;
    v4.assign(v3.begin(), v3.end());
    cout << "v4.assign(v3.begin(), v3.end()): ";
    for_each(v4.begin(), v4.end(), PrintMem);
    cout << endl;

    deque<int> v5;
    v5 = v4;
    cout << "v5 = v4: ";
    for_each(v5.begin(), v5.end(), PrintMem);
    cout << endl;

    cout << "元素互换前" << endl;
    cout << "v0: ";
    for_each(v0.begin(), v0.end(), PrintMem);
    cout << endl;
    cout << "v5: ";
    for_each(v5.begin(), v5.end(), PrintMem);
    cout << endl;
    cout << "元素互换后" << endl;
    v0.swap(v5);
    cout << "v0: ";
    for_each(v0.begin(), v0.end(), PrintMem);
    cout << endl;
    cout << "v5: ";
    for_each(v5.begin(), v5.end(), PrintMem);
    cout << endl;
    return 0;
}

 案例:

#include <iostream>
#include <string.h>
#include <vector>
#include <algorithm>

using namespace std;

class Person{
    friend Person WriteSore(Person &P);
public:
    vector<string> name;
private:
    vector<int> sore;

    static void Printer_s(string p){
         cout << p << " ";
    }
    static void Printer_i(int p){
         cout << p << " ";
    }
public:
    void PrintMem(){
        cout << "选手名字为: ";
        for_each(name.begin(), name.end(), Printer_s);
        cout << endl;
    }
    void PrintSore(int i, int num){
        cout << "各项分数为: ";
        for_each(sore.begin()+i*num, sore.begin()+i*num+num, Printer_i);
        cout << endl;
    }
    void check(){
        int mem = static_cast<int> (this->name.size());
        int num = static_cast<int>((static_cast<int> ((this->sore).size()))/mem);
        for(int i=0; i<mem; i++){
            cout << *(name.begin()+i) << endl;
            add(i, num);
        }
    }
    void add(int i, int num){
        int max = *(sore.begin()+i*num);
        int min = *(sore.begin()+i*num);
        int add_s = 0;
        for(int j=0; j<num; j++){
            add_s += *(sore.begin()+i*num+j);
            max = max > *(sore.begin()+i*num+j)? max:*(sore.begin()+i*num+j);
            min = min < *(sore.begin()+i*num+j)? min:*(sore.begin()+i*num+j);
        }
        cout << "总分: " << add_s << "; 平均分: " << add_s/num;
        if(num <= 2){
            cout << "; 无法计算中位平均分" << endl;
        }
        else{
            cout << "; 中位平均分: " << (add_s-max-min)/(num-2) << endl;
        }
    }
};

Person WriteName(int num){
    Person P;
    for(int i=0; i<num; i++){
        cout << "选手" << i+1 << "名称: ";
        string name;
        cin >> name;
        P.name.push_back(name);
        cout << "选手【" << *(P.name.end()-1) << "】已录入" << endl;
    }
    return P;
}

Person WriteSore(Person &P){
    cout << "设置评委数量: ";
    int num;
    cin >> num;
    for(int i=0; i<static_cast<int>(P.name.size()); i++){
        cout << "选手" << i+1 << ": " << P.name[i] << endl;
        for(int j=0; j<num; j++){
            cout << "评委" << j+1 << "打分: ";
            int s;
            cin >> s;
            if(s < 0){
                cout << "你在干嘛?恶意评分!!";
                break;
            }
            else{
                P.sore.push_back(s);
                cout << "分数" << s << "已录入" << endl;
            }
        }
        P.PrintSore(i, num);
    }
    return P;
}
int main()
{  
    cout << "选手数量:";
    int num;
    cin >> num;
    cout << endl;

    cout << "名称录入" << endl;
    Person P = WriteName(num);
    cout << endl;

    cout << "名称展示" << endl;
    P.PrintMem();

    cout << "成绩录入" << endl;
    WriteSore(P);
    cout << endl;

    cout << "成绩检查" << endl;
    P.check();
    cout << endl;
    return 0;
}

随机数

stack容器 栈容器(先进后出的数据结构)

 queue容器 队列容器

 list容器 链表容器

 链表的API

 

list存放自定义数据 如果删除某个节点 必须重载==运算符

 

list存放自定义数据 如果删除某个节点 必须重载<运算符

list存放自定义数据排序。执行排序规则

指定排序规则 只需要指定交换的条件

 使用仿函数

 仿函数回顾

lambda表达式介绍 

set/multiset容器 

 set的API

 lower_bound upper_bound

 equal_range

 对组(pair)

 仿函数修改set排序规则

#include <iostream>
#include <set>
#include <algorithm>

using namespace std;

class PX{
public:
    bool operator()(int val1, int val2) const{
        return val1 > val2;
    }
};

int main()
{
    //默认:小->大
    /*更改排序规则
     * set<int, 排序规则> P;
     * 其中<>中应该放类型,而有一种既可以是类型又可以是函数的就是仿函数
    */
    set<int, PX> P;
    P.insert(1);
    P.insert(4);
    P.insert(2);
    P.insert(5);
    P.insert(3);

    //打印 set的默认排序:从小到大
    for_each(P.begin(), P.end(), [](int val){ cout << val << " ";});
    cout << endl;
    return 0;
}

自定义数据指定排序规则

#include <iostream>
#include <string.h>
#include <set>
#include <algorithm>

using namespace std;

class PX{
public:
    string name;
    int age;
public:
    PX(string name, int age): name(name), age(age){}
};

class PP{
public:
    bool operator()(const PX &ob1, const PX &ob2) const{
        return ob1.age < ob2.age;
    }
};
int main()
{
    //默认:小->大
    /*更改排序规则
     * set<int, 排序规则> P;
     * 其中<>中应该放类型,而有一种既可以是类型又可以是函数的就是仿函数
    */
    set<PX, PP> P;
    P.insert(PX("A", 1));
    P.insert(PX("D", 4));
    P.insert(PX("B", 2));
    P.insert(PX("E", 5));
    P.insert(PX("C", 3));

    //打印 set的默认排序:从小到大
    for_each(P.begin(), P.end(), [](PX val){ cout << val.name << " ";});
    cout << endl;
    return 0;
}

自定义数据重载<运算符

#include <iostream>
#include <string.h>
#include <set>
#include <algorithm>

using namespace std;

class PX{
public:
    string name;
    int age;
public:
    PX(string name, int age): name(name), age(age){}

    bool operator<(const PX &ob) const{
        return this->age < ob.age;
    }
};

int main()
{
    //默认:小->大
    /*更改排序规则
     * set<int, 排序规则> P;
     * 其中<>中应该放类型,而有一种既可以是类型又可以是函数的就是仿函数
    */
    set<PX> P;
    P.insert(PX("A", 1));
    P.insert(PX("D", 4));
    P.insert(PX("B", 2));
    P.insert(PX("E", 5));
    P.insert(PX("C", 3));

    //打印 set的默认排序:从小到大
    for_each(P.begin(), P.end(), [](PX val){ cout << val.name << " ";});
    cout << endl;
    return 0;
}

multiset 允许插入重复的键值

map容器

 map的API

 打印

 find

map和vector配合使用

战队抽签

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <numeric> //极少算法在其中调用 例如:random_shuffle(v.begin, v.end())
//种子头文件
#include <stdlib.h>
#include <time.h>
using namespace std;

int main()
{
    //设置随机种子
    srand(time(NULL));
    //战队容器
    map<int, string> M;
    M.insert(make_pair(1, "RNG"));
    M.insert(make_pair(2, "DWG"));
    M.insert(make_pair(3, "EDG"));
    M.insert(make_pair(4, "TSM"));
    //战队编号容器
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    //随机洗牌,打乱容器中元素的顺序
    random_shuffle(v.begin(), v.end());
    //战队出场
    for_each(v.begin(), v.end(), [&](int k){cout << "战队【" << //[&]可以调用外部数据
                                                   M[k] << "】出场"<< endl;});

    cout << "Hello World!" << endl;
    return 0;
}

multimap容器

multimap键值可以重复,map键值不允许重复

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

int main()
{
    map<int, string> m;
    m.insert((make_pair(1, "RNG")));
    m.insert((make_pair(1, "EDG")));
    cout << m.count(1) << endl; //1

    multimap<int, string> m1;
    m1.insert((make_pair(1, "RNG")));
    m1.insert((make_pair(1, "EDG")));
    cout << m1.count(1) << endl; //2
    return 0;
}

 

#include <iostream>
#include <map>
#include <vector>

using namespace std;

class Person{
public:
    string name;
    Person(string name): name(name){}
};

void creatP(vector<Person> &v){
    v.push_back(Person("A"));
    v.push_back(Person("B"));
    v.push_back(Person("C"));
    v.push_back(Person("D"));
    v.push_back(Person("E"));
}
void join(vector<Person> &v, multimap<int, Person> &m){
    for(vector<Person>::iterator i=v.begin(); i != v.end(); i++){
        cout << "员工" << (*i).name << "加入部门(可选:1、2、3):" << endl;
        int delect = 0;
        cin >> delect;
        if(delect > 0 && delect < 4){
            m.insert(make_pair(delect, *i));
        }
        else{
            cout << "违规部门" << endl;
        }
    }
}
void print(multimap<int, Person>::const_iterator v, int num);
void show(multimap<int, Person> &m, int a){
    switch(a){
    case 1:
        cout << "------------" << endl;
        cout << "部门" << a << "共" << m.count(a) << "人" << endl;
        print(m.find(a), m.count(a));
        break;
    case 2:
        cout << "------------" << endl;
        cout << "部门" << a << "共" << m.count(a) << "人" << endl;
        print(m.find(a), m.count(a));
        break;
    case 3:
        cout << "------------" << endl;
        cout << "部门" << a << "共" << m.count(a) << "人" << endl;
        print(m.find(a), m.count(a));
        break;
    }
}
void print(multimap<int, Person>::const_iterator v, int num){
    for(int i=0; i<num; i++, v++){
//        cout << num << endl;
//        cout << i << endl;
        cout << "姓名:" << (*v).second.name << endl;
    }
}
int main()
{
    vector<Person> v;
    //创建员工
    creatP(v);
    multimap<int, Person> m;
    //加入部门
    join(v, m);

    //查看部门情况
    show(m, 1);
    show(m, 2);
    show(m, 3);
    return 0;
}

 

 

算法 

 谓词 返回值为bool类型的普通函数或函数对象

 

一元谓词 (案例:寻找)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//普通函数
bool than2(int val){
    return val>2;
}
//仿函数
class Than2{
public:
    bool operator()(int val){
        return val>2;
    }
};
int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    //普通函数 一元谓词
    vector<int>::iterator i0;
    i0 = find_if(v.begin(), v.end(), than2);
    if(i0 != v.end()){
        cout << "找到第一个大于2的数为:" << *i0 << endl;
    }
    else{
        cout << "未找到" << endl;
    }

    //仿函数 一元谓词
    vector<int>::iterator i1;
    i1 = find_if(v.begin(), v.end(), Than2());
    if(i1 != v.end()){
        cout << "找到第一个大于2的数为:" << *i1 << endl;
    }
    else{
        cout << "未找到" << endl;
    }
    return 0;
}

二元谓词(案例:比较)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//普通函数
bool px(int val0, int val1){
    return val0>val1;
}
//仿函数
class PX{
public:
    bool operator()(int val0, int val1){
        return val0<val1;
    }
};
int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    for_each(v.begin(), v.end(), [](int val){cout << val << " ";});
    cout << endl;
    //普通函数 二元谓词
    sort(v.begin(), v.end(), px);
    for_each(v.begin(), v.end(), [](int val){cout << val << " ";});
    cout << endl;
    //仿函数 二元谓词
    sort(v.begin(), v.end(), PX());
    for_each(v.begin(), v.end(), [](int val){cout << val << " ";});
    cout << endl;
    return 0;
}

 内建函数对象

适配器  扩展函数的参数接口

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//仿函数
class Than: public binary_function<int, int, bool>{
public:
    bool operator()(int val, int c) const {
        return val>c;
    }
};
int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);

    vector<int>::iterator i0;
    //适配器
    /*1、使用bind1st或bind2nd适配绑定参数
     *2、适配器中的函数必须是class类型的函数(也就是仿函数)
     *3、仿函数必须公共继承二元函数适配器class Than: public binary_function
     *4、参数萃取class Than: public binary_function<输入参数1类型, 输入参数2类型, 返回值类型>
     *5、const修饰仿函数bool operator()(int val, int c) const {}
    */
    i0 = find_if(v.begin(), v.end(), bind2nd(Than(), 2));
    if(i0 != v.end()){
        cout << "找到第一个大于2的数为:" << *i0 << endl;
    }
    else{
        cout << "未找到" << endl;
    }

    return 0;
}

bind2nd和bind1st的区别

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
class C: public binary_function<int, int, void>{
public:
    void operator()(int val0, int val1) const {
        cout << "第一参数val0:" << val0 << " 第二参数val1:" << val1 << endl;
    }
};

int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    cout << "-----bind1st-----" << endl;
    for_each(v.begin(), v.end(), bind1st(C(),2));
    cout << "-----bind12nd-----" << endl;
    for_each(v.begin(), v.end(), bind2nd(C(),2));

    return 0;
}

 

 取反适配器

一元取反适配器

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class great3: public unary_function<int, bool>{
public:
    bool operator()(int val) const{
        return val>3;
    }
};
int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);

    cout << "找出第一个大于3的数" << endl;
    vector<int>::iterator ret0;
    ret0 = find_if(v.begin(), v.end(), great3());
    cout << *ret0 << endl;
    cout << endl;

    cout << "取反适配器" << endl;
    /*一元取反适配器
     * 1、使用not1取反适配器 修饰取反的仿函数
     * 2、继承一元函数public unary_function
     * 3、参数萃取
     * 4、const修饰
    */
    cout << "找出第一个小于3的数" << endl;
    vector<int>::iterator ret1;
    ret1 = find_if(v.begin(), v.end(), not1(great3()));
    cout << *ret1 << endl;
    return 0;
}

总结: binary_function 二元继承  unary_function 一元继承

二元取反适配器

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class G: public binary_function<int, int, bool>{
public:
    bool operator()(int val0, int val1) const{
        return val0 < val1;
    }
};

class S{
public:
    bool operator()(int val0, int val1){
        return val0 < val1;
    }
};
int main()
{
    vector<int> v;
    v.push_back(2);
    v.push_back(1);
    v.push_back(4);
    v.push_back(3);

    cout << "默认sort从小到大排序" << endl;
    sort(v.begin(), v.end());
    for_each(v.begin(), v.end(), [](int val){cout << val << " ";});
    cout << endl;

    cout << "使用greater内建函数从大到小排序" << endl;
    sort(v.begin(), v.end(), greater<int>());
    for_each(v.begin(), v.end(), [](int val){cout << val << " ";});
    cout << endl;

    cout << "使用仿函数从小到大排序" << endl;
    sort(v.begin(), v.end(), S());
    for_each(v.begin(), v.end(), [](int val){cout << val << " ";});
    cout << endl;

    cout << "使用not2二元取反 从大到小排序" << endl;
    sort(v.begin(), v.end(), not2(G()));
    for_each(v.begin(), v.end(), [](int val){cout << val << " ";});
    cout << endl;

    cout << "使用内建函数取反 从小到大" << endl;
    sort(v.begin(), v.end(), not2(greater<int>()));
    for_each(v.begin(), v.end(), [](int val){cout << val << " ";});
    cout << endl;

    return 0;
}

 成员函数适配器

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
class Person{
public:
    string name;
    int age;
public:
    Person(string name, int age): name(name), age(age){}
    void show(){
        cout << "名字:" << name << " 年龄:" << age << endl;
    }
};

void SHow(Person &ob){
    cout << "名字:" << ob.name << " 年龄:" << ob.age << endl;
}
int main()
{
    vector<Person> v;
    v.push_back(Person("A", 1));
    v.push_back(Person("B", 2));
    v.push_back(Person("C", 3));
    v.push_back(Person("D", 4));
    cout << "普通函数遍历" << endl;
    for_each(v.begin(), v.end(), SHow);
    cout << endl;

    cout << "使用函数适配器mem_fun_ref 成员函数遍历" << endl;
    for_each(v.begin(), v.end(), mem_fun_ref(&Person::show));
    cout << endl;
    return 0;
}

 总结:

 函数指针适配器(普通函数作为适配器)

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void add(int val, int t){
    cout << val+t << " ";
}
int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    /*通常情况下bind2nd中函数应该是仿函数,普通函数是无法识别的
     * 可以通过ptr_fun将普通函数作为函数适配器
    */
    for_each(v.begin(), v.end(), bind2nd(ptr_fun(add), 10));
    cout << endl;
    return 0;
}

 

 常用的遍历算法

for_each

transform算法 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int swapp(int val){
    return val;
}
int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    //待搬运容器vv
    vector<int> vv;
    //设置vv大小
    vv.resize(v.size());
    //transform搬运
    //transform(v.begin(), v.end(), v.begin(), 搬运方式)
    transform(v.begin(), v.end(), vv.begin(), swapp);
    for_each(vv.begin(), vv.end(), [](int val){cout << val << " ";});
    cout << endl;
    return 0;
}

 常用的查找算法

 find

find_if 

 adjacent_find

 binary_search 二分法查找(容器必须有序)

 常用排序算法

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int swapp(int val){
    return val;
}
int main()
{
    vector<int> v0;
    v0.push_back(1);
    v0.push_back(3);
    v0.push_back(5);
    for_each(v0.begin(), v0.end(), [](int val){cout<<val<<" ";});
    cout << endl;

    vector<int> v1;
    v1.push_back(2);
    v1.push_back(4);
    v1.push_back(6);
    for_each(v1.begin(), v1.end(), [](int val){cout<<val<<" ";});
    cout << endl;

    vector<int> v;
    v.resize(v0.size()+v1.size());
    merge(v0.begin(), v0.end(), v1.begin(), v1.end(), v.begin());
    for_each(v.begin(), v.end(), [](int val){cout<<val<<" ";});
    cout << endl;

    return 0;
}

 sort算法

 random_shuffle算法

 常用拷贝和替换算法

 相同类型的两个容器交换swap

 算数生成算法

 常用集合算法

 结果:7 9

 set_difference 求差集

 STL案例

 

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <stdlib.h>
#include <time.h>

using namespace std;

class Person{
public:
    char name;
    vector<int> score;
    int num;
public:
    Person(char name, int num): name(name), num(num){}
    void pick(int v){
        score.push_back(v);
    }
};

void Print(map<int, Person> &ob){
    for_each(ob.begin(), ob.end(), [](pair<int, Person> v){
        cout << "编号:" << v.first << " 名字:" << v.second.name << endl;
    });
}

void Print(multimap<int, Person, std::greater<int>> &ob){
    for_each(ob.begin(), ob.end(), [](pair<int, Person> v){
        cout << "得分:" << v.first << " 名字:" << v.second.name << " 编号:" << v.second.num <<endl;
    });
}

void GetPerson(map<int, Person> &ob){
    int j = 65;
    int i =100;

    for(;i<124;i++, j++){
        char t = char(j);
        ob.insert(make_pair(i, Person(t, i)));
    }
}

vector<int> Race(vector<int> &z, map<int, Person> &m){
    vector<int> people;
    int i = z.size()/6;
    for(int j=0; j<i; j++){
        cout << "第" << j+1 <<"组出场" << endl;
        multimap<int, Person, std::greater<int>> mu;
        for(int jj=0; jj<6; jj++){
            int p = *(z.begin()+j*6+jj);
            cout << "编号:" << p << " 名字:" << m.find(p)->second.name;
            cout << "  打分:";
            int s = rand()%99 + 1;
            m.find(p)->second.pick(s);
            cout << *(m.find(p)->second.score.end()-1) << endl;

            //得分装入multimap容器排序  得分可能重复
            mu.insert(make_pair(s, m.find(p)->second));
        }
        cout << "第" << j+1 <<"组得分排序" << endl;
        Print(mu);
        cout << "第" << j+1 <<"组晋级名单" << endl;
        multimap<int, Person, std::greater<int>>::const_iterator it = mu.begin();
        people.push_back((*it).second.num);
        it++;
        people.push_back((*it).second.num);
        it++;
        people.push_back((*it).second.num);
        for_each(people.begin()+j*3, people.end(), [&](int v){
            cout << "编号:" << v << " 姓名:" <<
                    (*(m.find(v))).second.name <<
                    " 得分:" << *(m.find(v)->second.score.end()-1) <<endl;
        });
    }
    cout << "晋级总人数:" << people.size() << endl;
    return people;
}
int main()
{
    cout << "参赛成员录入" << endl;
    map<int, Person> m;
    GetPerson(m);
    Print(m);

    //创建抽签编号
    vector<int> z;
    int i =100;
    for(;i<124;i++){
        z.push_back(i);
    }
    //设置随机种子
    srand(time(NULL));
    cout << "-----随机分组1-----" << endl;
    random_shuffle(z.begin(), z.end());

    cout << "比赛1" << endl;
    //晋级人员
    vector<int> p1;
    p1 = Race(z, m);

    cout << "------随机分组2------" << endl;
    random_shuffle(p1.begin(), p1.end());

    cout << "比赛2" << endl;
    //晋级人员
    vector<int> p2;
    p2 = Race(p1, m);

    cout << "------随机分组3------" << endl;
    random_shuffle(p2.begin(), p2.end());

    cout << "比赛2" << endl;
    //晋级人员
    vector<int> p3;
    p3 = Race(p2, m);

    cout << "------最终成绩展示------" << endl;
    for_each(p3.begin(), p3.end(), [&](int v){
        cout << "编号:" << v << " 姓名:" <<
                (*(m.find(v))).second.name <<
                " 得分1:" << *(m.find(v)->second.score.begin()) <<
                " 得分2:" << *(m.find(v)->second.score.begin()+1) <<
                " 得分3:" << *(m.find(v)->second.score.begin()+2) << endl;
    });

    return 0;
}

注:仅学习总结

QT学习C++(16)_爱吃糖葫芦的大熊的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值