C++提高编程

模板

函数模板

#include <iostream>
using namespace std;
//定义函数模板
//开始
template <class T>  //class可以替换为typename
void mySwap(T &a,T &b){
    T temp = a;
    a = b;
    b = temp;
}
//结束

int main(){
    //使用函数模板
    int a = 10;
    int b = 20;
    //自动类型推导
    mySwap(a,b);
    //显示指定类型(推荐)
    mySwap<int>(a,b);
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
}

类模板

#include <iostream>
using namespace std;

template <class NameType,class AgeType>
class Person{
public:
    NameType m_Name;
    AgeType m_Age;

    Person(NameType name,AgeType age){
        this->m_Name = name;
        this->m_Age = age;
    }
    void print_Message()
    {
        cout << m_Name << endl;
        cout << m_Age << endl;
    }
};

int main(){
    Person<string,int> p1("张三",18);
    p1.print_Message();

}

STL

STL六大组件:

  • 容器
  • 算法
  • 迭代器
  • 仿函数
  • 适配器(配接器)
  • 空间配置器

vector容器

//vector基本使用
#include <iostream>
using namespace std;
#include <vector>
int main(){
    //创建vector容器
    vector<int> v;
    //向容器中插入数据
    v.push_back(10);
    v.push_back(20);
    //第一种遍历方式
    //v.begin()指向容器中第一个元素,v.end()指向容器中最后一个元素的下一个位置
    for(auto it = v.begin();it < v.end();++it){
        cout << *it << endl;
    }
    //第二种遍历方式
    //i是v中的元素
    for(int i : v){
        cout << i << endl;
    }
}
//vector存放自定义数据类型
#include <iostream>
using namespace std;
#include <vector>
class Person{
public:
    Person(string name,int age){
        this->m_Name = name;
        this->m_Age = age;
    }
    string m_Name;
    int m_Age;
};
int main(){
    vector<Person> v;
    Person p1("张三",18);
    Person p2("李四",19);
    v.push_back(p1);
    v.push_back(p2);

    for(auto it = v.begin();it < v.end();++it){
        //注意:it是指针类型
        cout << it->m_Name << ' ' << it->m_Age << endl;
    }
}
//vector容器嵌套容器
#include <iostream>
using namespace std;
#include <vector>

int main(){
    //大容器
    vector<vector<int>> v;
    //创建小容器
    vector<int> v1;
    vector<int> v2;
    //给小容器赋值
    for(int i = 0;i < 3;i++){
        v1.push_back(i);
        v2.push_back(i + 1);
    }
    //将小容器添加到大容器中
    v.push_back(v1);
    v.push_back(v2);
    //遍历大容器
    for(auto it = v.begin();it < v.end();++it){
        //注意:*it是小容器
        for(auto it1 = (*it).begin();it1 < (*it).end();++it1){
            cout << *it1 << ' ';

        }
        cout << endl;
    }
}

string容器

//string容器赋值操作
#include <iostream>
using namespace std;
#include <string>
int main(){
    string str;
    str.assign("hello C++"); //也可以直接str = "hello C++"

    string str1;
    str1.assign("hello C++",5);

    string str2;
    str2.assign(10,'w');

    cout << str << endl << str1 << endl << str2;
    //hello C++
    //hello
    //wwwwwwwwww
}
//string容器字符串拼接
#include <iostream>
using namespace std;
#include <string>
int main(){
    //通过+号
    string str = "hello";
    str = str + " world";
    //通过append
    string str1 = "hello";
    str1.append(" world");
    cout << str << endl << str1 << endl;
}
//字符串查找和替换
#include <iostream>
using namespace std;
#include <string>
int main(){
    //find从左往右查找
    //rfind从右往左查找
    string str = "hello";
  
    //注意:find函数返回的是下标
  
    int pos = str.find("ll");
    if(pos == -1){
        cout << "未找到字符串" << endl;
    } else{
        cout << "找到字符串,pos = " << pos << endl;  // 找到字符串,pos = 2
    }

    string str1 = "hello";
    str1.replace(1,3,"11111");
    cout << str1 << endl;   // h11111o
}
//string字符串比较
#include <iostream>
using namespace std;
#include <string>
int main(){
    string str1 = "hello";
    string str2 = "Hello";
    //可以直接 == ,因为重载了
    if(str1 == str2){
        cout << "两个字符串相等" << endl;
    } else{
        cout << "两个字符串不相等" << endl;
    }
}
//string字符存取
#include <iostream>
using namespace std;
#include <string>
int main(){
    string str = "hello";
    //遍历方式
    //c是str中的元素
    for(char c : str){
        cout << c  << ' ';
    }
}
//string字符串插入和删除
#include <iostream>
using namespace std;
#include <string>
int main(){
    string str = "hello";
    str.insert(1,"111"); //在1号位置前插入
    cout << str << endl; // h111ello

    string str1 = "hello";
    str1.erase(1,3); //从1号位置开始3个字符
    cout << str1 << endl; // ho
}
//string子串
#include <iostream>
using namespace std;
#include <string>
void test(){
    string email = "zhangsan@qq.com";
    int pos = email.find('@');
    string subStr = email.substr(0,pos);
    cout << subStr << endl;
}
int main(){
    string str = "hello";
    //获得子串的方法:从下标1开始,截取3个字符(str不变)
    string subStr = str.substr(1,3);
    cout << subStr << endl; // ell
    test(); // zhangsan
}

deque容器

//deque基本使用和vector类似
#include <iostream>
using namespace std;
#include <deque>
int main(){
    deque<int> d;
    //尾插
    d.push_back(10);
    //头插
    d.push_front(20);
    for(int i : d) {
        cout << i << ' ' << endl; // 20 10
    }

    //赋值
    deque<int> d1;
    d1 = d;
    for(int i : d1){
        cout << i << ' ' << endl; // 20 10
    }
}
//sort排序
#include <iostream>
using namespace std;
#include <deque>
#include <algorithm>
int main(){
    deque<int> d;
    d.push_back(30);
    d.push_back(20);
    d.push_front(10);
    for(int i : d){
        cout << i << ' ' << endl; // 10 30 20
    }
    sort(d.begin(),d.end());
    for(int i : d){
        cout << i << ' ' << endl; // 10 20 30
    }
}

stack容器

//stack容器基本使用
#include <iostream>
using namespace std;
#include <stack>
int main(){
    //栈(先进后出)不允许有遍历行为
    stack<int> s;
    //入栈
    s.push(10);
    s.push(20);
    s.push(30);

    while(!s.empty()){
        cout << "栈顶元素:" << s.top() << endl;
        //出栈
        s.pop();
    }
    cout << s.size() << endl; // 0
}

queue容器

//queue容器基本使用
#include <iostream>
using namespace std;
#include <queue>
class Person{
public:
    Person(string name,int age){
        this->m_Name = name;
        this->m_Age = age;
    }
    string m_Name;
    int m_Age;
};
int main(){
    //队列(先进先出)不允许有遍历行为
    queue<Person> q;
    Person p1("张三",18);
    Person p2("李四",19);
    q.push(p1);
    q.push(p2);
    while(!q.empty()){
        //查看队头
        cout << "队头元素:" << q.front().m_Name << ' ' << q.front().m_Age << endl;
        //查看队尾
        cout << "队尾元素:" << q.back().m_Name << ' ' << q.back().m_Age << endl;
        //出队
        q.pop();
    }
    cout << q.size() << endl; // 0
}

list容器

//list容器基本使用
#include <iostream>
using namespace std;
#include <list>

int main(){
    list<int> l;
    //尾插
    l.push_back(10);
    l.push_back(20);
    //头插
    l.push_front(30);
    l.push_front(10);
    //遍历
    //不支持随机访问,即不可以用[]访问list容器中的元素
    for(int i : l){
        cout << i << endl;
    }
    //迭代器
    auto it = l.begin();
    //头删
    l.pop_front();
    //尾删
    l.pop_back();
    //移除该元素,有多少个移除多少个
    l.remove(10);
}
//list容器反转和排序
#include <iostream>
using namespace std;
#include <list>

bool compare(int v1,int v2){
    return v1 > v2;
}

int main(){

    list<int> l;
    l.push_back(10);
    l.push_back(20);
    l.push_back(30);
    for(int i : l){
        cout << i << ' '; // 10 20 30
    }
    cout << endl;

    //反转
    l.reverse();
    for(int i : l){
        cout << i << ' '; // 30 20 10
    }
    cout << endl;

    //排序
    //报错sort(l.begin(),l.end());
    //所有不支持随机访问迭代器的容器,不可以用标准算法,但内部会提供对应一些算法
    l.sort(); //默认升序
    for(int i : l){
        cout << i << ' '; // 10 20 30
    }
    cout << endl;

    //降序
    l.sort(compare); // 传入函数名
    for(int i : l){
        cout << i << ' '; // 30 20 10
    }
}
'''排序案例:将Person自定义数据类型进行排序,Person中属性有姓名、年龄、身高。排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序。
'''
#include <iostream>
#include <list>
using namespace std;

class Person{
public:
    Person(string name,int age,int height){
        this->m_Name = name;
        this->m_Age = age;
        this->m_Height = height;
    }
    string m_Name;
    int m_Age{};
    int m_Height{};
};

bool compare(const Person& p1,const Person &p2){
    if(p1.m_Age == p2.m_Age){
        return p1.m_Height > p2.m_Height; //身高降序
    }else{
        return p1.m_Age < p2.m_Age; //年龄升序
    }
}

int main(){
    Person p1("刘备",35,175);
    Person p2("曹操",45,180);
    Person p3("孙权",40,170);
    Person p4("赵云",25,190);
    Person p5("张飞",35,160);
    Person p6("关羽",35,200);
    list<Person> l;
    l.push_back(p1);
    l.push_back(p2);
    l.push_back(p3);
    l.push_back(p4);
    l.push_back(p5);
    l.push_back(p6);
    l.sort(compare);
    for(Person p : l){
        cout << p.m_Name << ' ' << p.m_Age << ' ' << p.m_Height << endl;
    }
    //赵云 25 190
    //关羽 35 200
    //刘备 35 175
    //张飞 35 160
    //孙权 40 170
    //曹操 45 180
}

set/multiset容器

set容器无重复元素

multiset容器允许有重复元素

//set容器基本使用
#include <iostream>
#include <set>
using namespace std;

int main(){
    set<int> s;
    //插入数据,只有insert方式
    s.insert(10);
    s.insert(30);
    s.insert(20);
    s.insert(30);
    //set容器特点:所有元素插入后自动被排序、重复的元素会被过滤掉
    for(int i : s){
        cout << i << ' '; // 10 20 30
    }
    cout << endl;
    //删除
    s.erase(20);
    for(int i : s){
        cout << i << ' '; // 10 30
    }
}
//set容器查找和统计
#include <iostream>
#include <set>
using namespace std;

int main(){
    set<int> s;
    //插入数据,只有insert方式
    s.insert(10);
    s.insert(30);
    s.insert(20);
    s.insert(30);
    //find查找,返回迭代器指针(查到返回对应元素的迭代器,查不到返回m.end())
    auto it  = s.find(30);
    if(it != s.end()){
        cout << "找到了该元素: " << *it << endl; // 找到了该元素: 30
    } else{
        cout << "未找到该元素" << endl;
    }
    //count统计个数,值只能是1或者0
    int num = s.count(30);
    cout << num << endl; // 1
}
//pair对组基本使用
#include <iostream>
using namespace std;

int main(){
    //有参构造
    pair<string,int> p("Tom",15);
    cout << p.first << ' ' << p.second << endl;
}
//set容器排序
#include <iostream>
using namespace std;
#include <set>
class compare{
public:
    //仿函数
    bool operator()(int a, int b){
        return a > b;
    }
};
int main(){
    //排序,必须插入元素之前指定规则
    set<int,compare> s1;
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
    s1.insert(25);
    for(int i : s1){
        cout << i << ' '; // 40 30 25 20
    }
}

map/multimap容器

map容器:不允许容器中有重复的key值元素,按key值自动排序,每一个元素都是pair对组

multimap容器:允许容器中有重复key值元素

//map容器的基本使用
#include <iostream>
#include <map>
using namespace std;

int main(){
    map<int,int> m;
    m.insert(pair<int,int>(1,10));
    m.insert(pair<int,int>(3,10));
    m.insert((pair<int,int>(2,10)));
    //遍历方式 或 for(auto it = m.begin();it != m.end();++it)
    for(auto i : m){
        //i是m中的元素
        cout << i.first << ' ' << i.second << endl;
        // 1 10
        // 2 10
        // 3 10
    }
}
//map容器查找和统计
#include <iostream>
#include <map>
using namespace std;

int main() {
    map<int, int> m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(3, 30));
    m.insert((pair<int, int>(2, 20)));
    //find通过key值查找,返回迭代器指针(查到返回对应元素的迭代器,查不到返回m.end())
    auto it = m.find(3);
    if(it != m.end()){
        cout << "找到了该元素,value为:" <<  it->second << endl; // 30
    } else{
        cout << "没找到" << endl;
    }
    //count统计,值只能是1或0
    int num = m.count(3);
    cout << num << endl; // 1
}
//map容器排序
#include <iostream>
#include <map>
using namespace std;

class compare{
public:
    //仿函数
    bool operator()(const int &a, const int &b){
        return a > b;
    }
};

int main() {
    //排序,必须先指定排序规则再插入
    map<int, int,compare> m;
    m.insert(make_pair(1, 10));
    m.insert(make_pair(3, 30));
    m.insert(make_pair(2, 20));
    for(auto i : m){
        cout << i.first << ' ' << i.second << endl;
    }
}

函数对象

也叫仿函数,本质是类

谓词

#include <iostream>
using namespace std;
#include <vector>
//谓词:返回bool类型的仿函数
//一元谓词:operator()接受一个参数
//二元谓词:operator()接受两个参数
class GreaterFive{
public:
    bool operator()(int val){
        return val > 5;
    }
};
int main(){
    vector<int> v;
    for(int i = 0;i < 10;i++){
        v.push_back(i);
    }
    auto it = find_if(v.begin(),v.end(),GreaterFive());
    if(it == v.end()){
        cout << "没找到" << endl;
    } else{
        cout << "找到了:" << *it << endl; // 找到了:6
    }
}

常用算法

//find和find_if用法
#include <iostream>
#include <vector>
using namespace std;
class GreaterFive{
public:
    bool operator()(int a){
        return a > 5;
    }
};
int main(){
    vector<int> v;
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    //find查找,返回迭代器
    auto it = find(v.begin(),v.end(),10);
    if(it == v.end()){
        cout << "没找到" << endl;
    } else{
        cout << "找到了:"  << *it << endl; // 找到了:10
    }

    //find_if查找
    //注意:谓词传匿名对象,函数传函数名
    auto it_if = find_if(v.begin(),v.end(),GreaterFive());
    if(it_if == v.end()){
        cout << "没找到" << endl;
    } else{
        cout << "找到了:"  << *it_if << endl; // 找到了:10
    }
}
//查找相邻重复元素
#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(4);
    v.push_back(4);
    v.push_back(5);

    auto it = adjacent_find(v.begin(),v.end());
    if(it == v.end()){
        cout << "找不到" << endl;
    } else{
        cout << "找到相邻重复元素" << *it << endl; // 找到相邻重复元素2
    }
}
//二分查找(必须是有序序列),查找指定元素是否存在,返回bool值
#include <iostream>
#include <vector>
using namespace std;
int main() {
    vector<int> v;
    v.push_back(1);
    v.push_back(3);
    v.push_back(2);
    v.push_back(2);
    v.push_back(4);
    v.push_back(4);
    v.push_back(4);
    v.push_back(5);
    sort(v.begin(),v.end());
    bool b = binary_search(v.begin(),v.end(),2);
    cout << b << endl; // 1
    //count统计
    int num = count(v.begin(),v.end(),4);
    cout << num << endl; // 3 
}
//求两个容器的交集、差集、并集
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
    vector<int> v1;
    vector<int> v2;
    for(int i = 0;i < 10;i++){
        v1.push_back(i); // 0 1 2 3 4 5 6 7 8 9
        v2.push_back(i + 5); // 5 6 7 8 9 10 11 12 13 14
    }
    //目标容器需要提前开辟空间

    //求交集set_intersection
    vector<int> v3;
    v3.resize(min(v1.size(),v2.size()));
    //返回迭代器
    auto end = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
    for(auto it = v3.begin();it != end;++it){
        cout << *it << ' '; // 5 6 7 8 9
    }
    cout << endl;

    //求并集set_union
    vector<int> v4;
    v4.resize(v1.size() + v2.size());
    auto end1 = set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),v4.begin());
    for(auto it = v4.begin();it != end1;++it){
        cout << *it << ' '; // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
    }
    cout << endl;

    //求差集set_difference
    vector<int> v5;
    v5.resize(max(v1.size(),v2.size()));
    //v1 - v2
    auto end2 = set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),v5.begin());
    for(auto it = v5.begin();it != end2;++it){
        cout << *it << ' '; // 0 1 2 3 4
    }
}
上一篇:误操作删除了performance_schema和sys库恢复方式


下一篇:Antd组件Table树型多选全选问题