bilibili
学习笔记
平台bilibili知识点:class指针模板STL标准库string容器vector内置方法#pragra once; 防止重 includesystem("pause") 按任意继续system("cls") 清屏int numcin>>num 输入exit(0) 退出整个程序堆区创建数据 返回指针int *p = new int(10) 初始化值为10delete 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中是protectedclass B:private A{} B继承A A的成员在B中是privateclass B:virtual public A{} 虚继承,解决菱形继承的结成数据冲突多态 virtualclass 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 或falsev.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 > str2res<0 str1 < str2string 插入str.insert(1,"aaa") 在str 第1个位置插入 aaastring 删除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的元素方法同dequelst.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>插入数据只有insertset<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中的removeset<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>所有元素都是pairpair中一个元素为key,启动索引作用,第二个元素为value 实值所有元素都会根据key值自动排序map不允许有重复key,mutimap允许有重复keymap<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)自定义排序规则同setfind_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) 返回-50plus<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_andlogical_orlogical_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的值搬运给v2class 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岁的人的 个数常用的排序算法sortrandom_shuffle 洗牌,指定范围内的元素随机调整次序mergereverse常用的拷贝和替换算法copyreplacereplace_ifswap(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完