云起工作室 15711107967
bilibili 学习笔记
2022-11-25 22:03:16

平台bilibili


知识点:

class

指针

模板

STL标准库

string

容器vector

内置方法


#pragra once; 防止重 include


system("pause") 按任意继续

system("cls") 清屏


int num

cin>>num 输入


exit(0) 退出整个程序


堆区创建数据 返回指针

int *p = new int(10) 初始化值为10

delete p ;释放堆区内存

int *p = new int[10] 数组

delete [] p;



赋值拷贝

class Person{

Person(const Person *p);//赋值拷贝构造函数

Person & operator=(const Person& p) // operator 防止浅拷贝

public:

string name;

}

Person a;

Person b = a; //赋值拷贝



继承 private成员不可继承

class B:Public A{} B继承A A的public、protected 成员不变

class B:prottected A{} B继承A A的成员在B中是protected

class B:private A{} B继承A A的成员在B中是private


class B:virtual public A{} 虚继承,解决菱形继承的结成数据冲突


多态 virtual

class animal{

virtual void speck(){ 虚函数, 调用&animal时会被覆盖

cout << " a speck" << endl;

}

virtual int ask()=0; 纯虚函数;有纯虚函数的类不可以实例化

}

class cat:public animal{

void speck(){

cout << " b speck" << endl;

}

}

调用

function speck(animal &animal){

animal.speck();

}

cat c;

speck(c)父speck 没有 virtual 输出 a speck,父方法有virtual 输出 b speck




文件读写

引用头文件

#include <fstream>


ofstream 写操作

ifstream 读操作

fstream 读写操作


ios::in 打开要读取的文件

ios::out 打开要写入的文件

ios::binary 以二进制模式打开文件

ios::app 打开文件在末尾附加新信息

ios::ate 打开并将空间移动到文件末尾

ios::trunc 删除现有文件中的数据

ios::nocreate 尽在文件已存在是打开文件

ios::noreplace 尽在文件不存在时打开文件


写文件

fstram fs;

fs.open("test.txt",ios::out|ios::binary);

fs<< "内容" <<endl;

fs.close();


二进制方式写文件

fstream fs("test.txt",ios::out|ios::binary)

fstram fs;

fs.open("test.txt",ios::out|ios::binary);

Person zhangsan = {"张三",18}

fs.write((const char *)&zhangsan,sizeof(张三));

fs.close();


读二进制文件

ifstream ifs;

ifs.open("text.txt",ios::in|ios::binary);

if(!ifs.is_open()){

return ;

}

Person p;

ifs.read((char *)&p,sizeof(p));

ifs.close();



fstream fs;

fs.open("text.txt",ios::in);

if(!fs.is_open){

cout << "文件不存在"<<endl;

}

char ch; //定义一个字符,读取一个字符就到了末尾标志eof 说明是空文件

fs>>ch;

if(fs.eof){

cout << "文件存在但为空"<<endl;

}



** 问题不懂可以多看几遍 p154

Work ** Emplor = new Work *[5]

delete [] Emplor;


switch case里如果代码太多没有{} 会报错

switch(type)

case 1:

{

break;

}



模板

template<typename T> 或 template<class T> //自定义数据类型 T

使用方法

1、自动类型推导

mySwap(a,b);

2、显示指定类型

mySwap<int>(a,b);

void mySwap(T &a,T &b){

逻辑实现

}


template<class T>

void swap() //swap 方法里要用到自定义模板

{}


类模板

template<typaname tname,typename tage>

class Person{

public:

tname name;

tage age;

Person(tname nm,tage ag){

name=nm;

age = ag;

}

}

调用

Person<string,int> p1("张三",18);


template<typaname tname,typename tage=int> 默认tage是int类型



查看类型

typeid(T1).name(); 查看T1类型


类模板与友元

一、类内实现

template<class T1,class T2>

class Person{

friend void printPerson(Person<T1,T2> &p){

//逻辑实现

};

public:

T1 name;

T2 age;

}

二、类外实现

1、template<class T1,class T2>

class Person;

2、template<class T1,class T2>

void printPerson(Person<T1,T2> &p){

}

3、template<class T1,class T2>

class Person{

friend void printPerson<>(Person<T1,T2> &p); // <>至关重要

public:

T1 name;

T2 age;

}


STL六大组件

1、容器:如:vector、deque、stack、list、set、map等

2、算法:如sort、find、copy、for_each #include <algorithm>

3、迭代器:扮演了容器与算法之间的胶合剂

4、仿函数:行为类似函数,可作为算法的某种策略

5、适配器:一种永凯修饰容器或者仿函数或迭代器接口的东西

6、空间配置器:负责空间的配置与管理



vector

#include <vector>

#include <algorithm> 标准算法头文件

vector<int> v;

v.push_back(10);

v.push_back(20); ……

遍历方法一

vector<int>::iterator itBegin = v.begin();

vector<int>::iterator itEnd = v.end();

while(itBegin!=itEnd){

cout << *itBegin << endl;

}

遍历方法二

for(vector<int>::iterator it=v.begin();it!=v.end();it++){

cout << *it << endl;

}

遍历方法三

void myPrint(int val){

cout<< val << endl;

}

for_each(v.begin,v.end,myPrint)


vector<int> v;

v.empty() 判断是否为空 返回true 或false

v.capacity() 获取容器容量

v.size() 获取容器数据个数

v.resize(num) 重新指定容器容量,如果变小,最后的元素会被删除

v.resize(num,ele) 重新指定容器容量大小,如果边长则以ele填充


v.push_back(ele) 尾部添加

v.pop_back() 删除最后一个

v.clear() 删除容器中所有元素

v.insert(v.begin(),2,100); 在容器前边插入两个100 迭代器插入

v.erase(v.begin()) 删除容器第一个元素

v[i] 也可以用v.at(i)

v.front() 返回第一个元素

v.back() 返回最后一个元素

v1.swap(v2) v1 与 v2 交换

vector<int>(v).swap(v) 内存收缩

v.reserve(num) 预留空间


string赋值

string str = ""

string str.assign("");

string 拼接

string str+=""

string str.append("")

string查找

find() rfind()

string 替换

replace(int,int,string)


字符串比较

int res = str1.compare(str2)

res==0 两字符串相等

res>0 str1 > str2

res<0 str1 < str2


string 插入

str.insert(1,"aaa") 在str 第1个位置插入 aaa

string 删除

str.erase(1,3) 从第一个位置开始,擦除3个字符

字符串截取

str.substr(1,3)


#include <deque>

deque 与vector的区别

vector 对于头部插入删除效率低,,数据量越大,效率越低

deque 相对而言,对头部的插入删除速度会比vector快

vector访问元素的速度会比deque快,这和两者内部实现有关

deque<int> d;

d.push_front(ele) 头部添加元素 vector 没有

d.pop_front() 头部删除元素 vector 没有

d.push_back(ele) 尾部添加元素

d.pop_back() 尾部删除元素

iterator 或const_iterator


#include <algorithm>

sort(d.begin(),d.end()) 默认升序排列


随机数种子

#include <ctime>

srand( (unsigned int)time(NULL) )


stack 容器

先进后出,不可遍历

stack<int> s;

s.empty() 判断是否为空

s.push(ele) 入栈

s.top(); 获取栈顶元素

s.pop(); 出栈 删除顶部元素


queue 容器

先进先出 不可遍历

queue<int> q;

q.push(ele) 在队尾添加元素

q.pop() 从对头移除第一个元素

q.back() 返回最后一个元素

q.front() 返回第一个元素



list 容器

#include <list>

list <int> lst;

lst[0] 错误,不可以用[索引] 访问 也不可已用 at(索引)访问

lst.push_back();

list<int> l2(lst.begin(),lst.end()); 构造

l2.assign(lst.begin(),lst.end);

list<int> l3(l2); 构造

l3.assign(l2);

list<int> l4(10,100); 构造,创建10 值为100的元素

方法同deque

lst.push_back(ele)

lst.pop_back()

lst.push_front(ele)

lst.pop_front()

lst.insert(pos,ele)

lst.insert(pos,n,ele)

lst.insert(pos,begin,end)

lst.clear()

lst.erase(begin,end)

lst.erase(pos)

附加方法

lst.remvoe(ele) 删除值为ele的所有元素


lst.front() 返回第一个元素

lst.back() 返回最后一个元素

lst.reverse() 翻转 ,收尾对调

lst.sort() 排序 默认升序排列 注:vector 是 sort(v.begin(),v.end())


bool mysort(int a,int b){

return a>b; //降序排列

return a<b; //升序排列

}

lst.sort(mysort)



list<int>::iterator it = lst.begin()

it++ 可以

it+=1 或it = it+1 不不不可以




set/multiset 容器

set 不允许有重复元素,插入数据会自动排序

multiset 允许有重复元素

#include <set>

插入数据只有insert

set<int>s;

s.insert(10) 不可用push_back(ele)

set<int> s2(s) 拷贝构造

set<int> s3=str2 复制拷贝

s.erase(s.begin())

s.erase(30) 将值为30的元素删掉,相当于list中的remove

set<int>::iterator pos = s.find(ele)

if(pos!=s.end()){有}

int num = count(ele) 对于set 返回结果只有0或1,


<!-- 指定排序规则 仿函数-->

class mysort{

public:

bool operator()(int v1,int v2){ // 重定义()

return v1>v2;

}

}

set<int,mysort> s;

s.insert(10)

s.insert(20)

for(set<int,int,mysort>::iterator it =s.begin();it!=s.end();it++){

cout<< (*it) << endl;

}


pair 对组数据

pair<string,int>p("tom",20);

pair<string,int>p = make_pair("tom",20);

cout<< "姓名:"<<p.first << "年龄:" << p.second<<endl;






map /mutimap 容器

#include<map>

所有元素都是pair

pair中一个元素为key,启动索引作用,第二个元素为value 实值

所有元素都会根据key值自动排序

map不允许有重复key,mutimap允许有重复key

map<int,int> m;

m.insert(pair<int,int>(1,10)) 插入方法一

m.insert(make_pair(2,10)) 插入方法二

m.insert(map<int,int>::value_type(3,30)) 插入方法三

m[4] = 40 插入方法四

for(map<int,int>::iterator it = m.begin();it!=m.end();it++){

cout<< "key="<<(*it).first << " value = " << it->second<<endl;

}


m.erase(m.begin()) 删除第一个元素

m.erase(3) 删除key 为3 的元素

map<int,int>::iterator it= m.find(key) 查找

if(it!=m.end()){找到}

int num = count(key)

自定义排序规则同set



find_if();

class GreatFive{

public:

bool operator()(int val){

return val>5;

}

}

vector<int>::iterator it = find_if(v.begin(),v.end(),GreatFive())

if(it!=v.end()){

"有大于5的数"

}



sort() // 默认正序

class MySort{

public:

bool operator()(int a,int b){

return a> b;

}

}

vector<int> v;

sort(v.begin(),v.end()) 升序

sort(v.begin(),v.end(),MySort) 降序排列





#include <functional> // 内置仿函数

一、运算仿函数

plus 加法

minus 减法

multiplies 乘法

divides 除法

modulus 取模

megate 取反


negate<int> n; 取反

n(50) 返回-50


plus<int> p; 相加

p(10,20) 返回30


二、关系仿函数

equal_to 等于

not_equal_to 不等于

greater 大于

greater_equal 大于等于

less 小于

less_equal 小于等于


sort(v.begin(),v.end(),greater<int>()) greater 是自带的


三、逻辑仿函数

logical_and

logical_or

logical_not


vector<bool> v1;

v.push_back(true)

v.push_back(false)

v.push_back(true)

v.push_back(false)

vector<bool> v2;

v.resize(v1.size()) //搬运必须小开辟空间

transform(v1.begin(),v1.end(),v2.begin(),logical_not<bool>()) v1元素取反付给v2



常用算法

#include <algorithm>

for_each

transform


<!-- 普通函数定义 -->

void bianli1(int val){

cout << val << endl;

}

<!-- 仿函数定义 -->

class bianli2{

public:

void operato ()(int val){

cout << val << endl;

}

}

vector<int> v;

for_each(v.begin(),v.end(),bianli1) 普通函数遍历

for_reach(v.begin(),v.end(),bianli2()) 仿函数遍历


transform 搬运 即将 v1的值搬运给v2

class yunsuan{

public:

int operator ()(int){

return int+1000

}

}

vector<int> v1;

vector<int> v2;

v2.resize(v1.size())

transform(v1.begin(),v1.end(),v2.begin(),yunsuan())



常用的查找算法

find 查找元素

find_if 按条件查找元素

adjacent_find 查找相邻重复元素 返回相邻重复元素第一个元素迭代器

binary_search 二分查找法 返回bool 容器必须是有序的

count 统计元素个数

count_if 按条件统计元素个数


vector<int>::iterator it = find(v.begin(),v.end(),val) 返回迭代器


find 查找自定义类型数据

class Person{

public:

Person(string name,int age){

this->m_name = name;

this->m_age = age;

}

<!-- 重载 == 使底层知道如何对比自定义数据类型person -->

bool operator == (Person &a,Person $b){

if(a.m_name==b.m_name && a.age==b.age){

return true;

}else{

return false;

}

}

string m_name;

int age;

}

vector<Person> v;

Person p("zhangsan",18)

vector<Person>::iterator it = find(v.begin(),v.end(),p)

if(it==v.end){未找到}


vector<int>::iterator it = adjacent_find(v.begin(),v.end()); v必须是有序的

bool has = binary_search(v.begin(),v.end(),val);

int num = count(v.begin(),v.end(),val) 查找val个数


统计自定义类型

vector<Person> v;

class Person{

public:

Person(string name,int age){

this->m_name = name;

this->m_age = age;

}

bool operator == (const Person &a){

if(this->age==a.age){

return true;

}else{

return false;

}

}

string m_name;

int age;

}

Person p("赵云",35)

int num = count(v.begin(),v.end(),p) 35岁的人的 个数



常用的排序算法

sort

random_shuffle 洗牌,指定范围内的元素随机调整次序

merge

reverse

常用的拷贝和替换算法

copy

replace

replace_if

swap(v1,v2) 交换


vector<int> v1;

vector<int> v2;

v2.resize(v1.size());

copy(v1.begin(),v1.end(),v2.begin())


replace(v.begin(),v.end(),oldValue,newValue)


class MyGreater{

public:

void operator()(int val){

return val>30

}

}

replace_if(v.begin(),v.end(),MyGreater(),500) 把大于30的元素都替换成500


常用的算术生成算法

#include <numeric>

accumulate 计算容器元素累计总和

fill 向容器中添加元素


accumulate(v.begin(),v.end(),0) 返回容器元素的和

fill(v.begin(),v.end(),100) 将容器中元素填充成100



<!-- 常用的集合算法 -->

set_intersection //求两个容器的交集

set_union //求两个容器的并集

set_difference //求两个容器的差集


vector<int> targetV;

targetV.resize(min(v1.size(),v2.size()))

vector<int>::iterator itEnd = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),targetV.begin())

for_each(targetV.begin(),itEnd,Myprint) 用itEnd 是因为 targetV 的元素比resize()时定义的量要少


vector<int> targetV;

targetV.resize(v1.size()+v2.size())

vector<int>::iterator itEnd = set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),targetV.begin())

for_each(targetV.begin(),itEnd,Myprint)


targetV.resize(max(v1.size(),v2.size()))

vector<int>::iterator itEnd = set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),targetV.begin())

p250完