C++ 提高编程

一、string 

二、vector

三、deque

四、stack

五、queue

六、list

七、set /multiset

八、map /multimap

九、函数对象/仿函数

十、常用算法

一、模板

C++ 除了面向对象编程外,还有一种编程思想为泛型编程

模板的作用:建立通用函数,返回类型与参数类型都不指定,用虚拟的类型代表

语法

template <typename T>

#include<iostream>
using namespace std;

template<typename T>
void swapNumber(T &a, T &b) {
    T temp = a;
    a = b;
    b = temp;
}

int main() {
    int a = 10;
    int b = 20;
    //1.隐士类型转换
    //swapNumber(a,b);

    //2.显示类型指定
    swapNumber<int>(a, b);
    cout << a << endl;
    cout << b << endl;
    return 0;
}

普通函数可以发生隐式类型转换 

函数模板自动类型推导不会发生隐式类型转换,但是显示指定类型可以发生隐士类型转换

普通函数与函数模板的调用规则

  1. 普通函数与函数模板都可以调用,优先调用普通函数
  2. 可以通过空模板参数列表强制调用函数模板
  3. 函数模板可以发生函数重载
  4. 如果函数模板有更好的匹配,优先调用函数模板

类模板:类模板没有自动类型推导,类模板参数列表可以有默认参数

定义: template<T>  类

类模板成员函数的创建时机1

类模板成员函数在调用时才创建

备注:

typeid() 获取指定数据的类型 

climit 头文件包含数据类型的极值

类模板与继承

子类继承父类,如果父类是类模板,那么需要指定父类的模板类型

 二、string

string 本质上是一个类,内部维护了一个 char *

string 赋值可以通过 = 或者 assign  

string 字符串拼接 , 通过 += 或者 appent

查找与替换  find  rfind ,区别是find 从左往右边查,rfind 从右往左查询 。replace ,替换,可以将指定位置的字符替换为目标字符串

string 字符串比较 compare ,相等为0 ,逐个字符比较

string 内部重载了 [] , 也可以通过 at 访问单个字符

字符串插入与删除  insert  ,erase 删除 ,下标都是从 0 开始计数

子串,substr ,指定开始位置与长度,截取子串

三、vector 容器

特点:

Vector 数据结构和数组非常相似,称为单端数组

vector 可以动态扩展

使用需要包含头文件 <vector>

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

int main() {
    vector<int> v1;
    for (int i = 0; i < 10; i++) {
        v1.push_back(i);
    }
    printVector(v1);
    return 0;
}

四、deque

使用需要先包含头文件 <deque>

双端数组,可以对头端与尾端进行操作

deque 内部工作原理:

deque 内部有个中控器,维护每端缓冲区的地址

deque 容器的迭代器也支持随机访问

deque 没有容量的概念,可以无限扩大

算法头文件 <algorithm> ,可以使用 sort 排序 ,支持随机访问的容器都可以通过 sort 进行排序

rand() 可以获取随机数, 伪随机,

rand((unsigned int)time(null))

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

五、stack 

 栈容器 stack ,是一种 先进后出 FILO 的数据结构,栈不允许有遍历的行为,每次只能访问栈顶元素

int main() {
    using namespace std;
    stack<int>s;
    s.push(10);
    s.push(20);while (!s.empty()) {
        cout << s.top() << endl;
        s.pop();
    }
    return 0;
}

 STL 中使用栈,需要包含头文件 <stack>

六、queue

队列,是一种先进先出的数据结构 FIFO,一端只能进数据,一端只能出数据。访问数据也只能访问2端的数据

int main() {
    queue<int>q;
    q.push(30);
    q.push(40);while (!q.empty()) {
        cout << q.front() << endl;
        q.pop();
    }
    return 0;
}

 七、list

功能:将数据进行链式存储

链表:是一种物理上存储非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针实现的

int main() {
    list<int> in;
    in.push_back(50);
    in.push_back(10);
    in.push_back(20);in.sort();
    in.reverse();
    for (list<int>::iterator it = in.begin(); it != in.end(); it++) {
        cout << *it<<endl;
    }
    //sort(); 标准算法的排序只能够随机访问的数据结构
    return 0;
}

 八、set /multiset

包含头文件 <set>

set 容器,不允许存储重复的元素 multiset 允许插入重复的元素

set 容器特点

  1. 容器元素插入会自动排序
  2. 不允许插入重复元素
int main() {
    
    set<int, MyCompare> s;
    s.insert(10);
    s.insert(40);
    s.insert(20);for (set<int, MyCompare>::iterator it = s.begin(); it != s.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}

在 visio studio 下编译会报错,需要在仿函数中加入 const

九、map / multimap

包含头文件 <map>

map 中所有的元素都是 pair(对组)

所有的元素都会根据元素的键自动排序

map 与 multimap 区别是key 值是否允许重复

队组: pair<int,int>(1,10) ,make_pair(1,20)

class Mycompare {
public:
    bool operator()(int x,int y)const {
        return x > y;
    }
};

int main() {
    map<int, int, Mycompare>m;
    m.insert(make_pair(1, 10));
    m.insert(make_pair(2, 20));
    m.insert(make_pair(3, 30));
    m.insert(make_pair(4, 40));
    for (map<int, int, Mycompare>::iterator it = m.begin(); it != m.end(); it++) {
        cout << it->first << "," << it->second << endl;
    }
    return 0;
}

十 、函数对象(仿函数)

函数对象/仿函数是一个类 

重载函数调用操作符,其对象常称为函数对象

函数对象使用重载 () 时,行为类似函数调用,叫做仿函数

谓词

如果bool 类型作为返回值的仿函数

一元谓词

operator() 接收一个参数

二元谓词

operator() 接收2个参数

内建函数对象

包含头文件  <functional>

  1. 算术仿函数
  2. 关系仿函数
  3. 逻辑仿函数

算术仿函数

negate  取反

plus 加法

关系仿函数

equal

less

greater_equal

逻辑仿函数

logical_and

logical_or

logical_not

注意:transform 算法函数搬运

十一、常用算法

算法需要导入头文件

#include<algorithm>

11.1 遍历算法foreach 

函数可以是普通函数/

class Print {
public:
    void operator()(int i) {
        cout << i<<" ";
    }

};

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

int main() {
    vector<int> v;
    for (int i = 1; i < 10; i++) {
        v.push_back(i);
    }

    for_each(v.begin(),v.end(), Print());
    cout << endl;
    for_each(v.begin(), v.end(), myPrint);
    return 0;
}

11.2 transform 搬运到另一个容器

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

int transInt(int i) {
    return i+100;
}

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

int main() {
    vector<int> v1;
    for (int i = 1; i < 10; i++) {
        v1.push_back(i);
    }
    vector<int>v2;
    v2.resize(v1.size());
    transform(v1.begin(),v1.end(),v2.begin(), transInt);
    for_each(v1.begin(), v1.end(), myPrint);
    cout << endl;
    for_each(v2.begin(), v2.end(), myPrint);
    return 0;
}

11.3 find  查找元素,返回迭代器

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


int main() {
    vector<int> v1;
    for (int i = 1; i < 10; i++) {
        v1.push_back(i);
    }
    
    vector<int>::iterator it = find(v1.begin(), v1.end(), 1);

    if (it != v1.end()) {
        cout << "找到元素:" << *it << endl;
    }
    else {
        cout << "未找到元素" << endl;
    }

    return 0;
}

11.4 find_if 按条件查找

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


class Greater20 {
public:
    bool operator()(int i) {
        return i > 20;
    }
};

int main() {
    vector<int> v1;
    for (int i = 1; i < 30; i++) {
        v1.push_back(i);
    }
    
    vector<int>::iterator it = find_if(v1.begin(), v1.end(), Greater20());

    if (it != v1.end()) {
        cout << "找到元素:" << *it << endl;
    }
    else {
        cout << "未找到元素" << endl;
    }
    return 0;
}

11.5 adjacent_find 查询相邻重复元素

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

int main() {
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(30);
    v1.push_back(30);
    v1.push_back(10);
    v1.push_back(50);

    vector<int>::iterator it = adjacent_find(v1.begin(), v1.end());

    if (it != v1.end()) {
        cout << "找到元素:" << *it << endl;
    }
    else {
        cout << "未找到元素" << endl;
    }
    return 0;
}

11.6 binary_search 二分查找有序数组是否存在某元素

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

int main() {
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);

    bool res = binary_search(v1.begin(), v1.end(),30);

    if (res) {
        cout << "找到元素:" << endl;
    }
    else {
        cout << "未找到元素" << endl;
    }
    return 0;
}

11.7 count 统计数据出现次数

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

int main() {
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(10);
    v1.push_back(50);

    int res = count(v1.begin(), v1.end(),10);
    cout << res << endl;
    return 0;
}

参考笔记:https://blog.csdn.net/ClaireSy/article/details/108423061

视频:https://www.bilibili.com/video/BV1et411b73Z

posted @ 2020-11-26 12:54  byebai95  阅读(222)  评论(0编辑  收藏  举报