学习记录

学习记录

三月 01, 2020

第七章

流操纵算子

需要头文件
#include
整数dec10,oct8,hex16,setbase
小数点setiosflags(ios::fixed)或fixed
浮点精度precision,setprecision
取消小数点resetiosflags(ios::fixed)
科学计数法scientific
设置宽域setw,width
非负数显示正号showpos()
非负数不显示正号noshowpos()
填充符号setfill(‘’)
数字的位置left,right

模板

templatea//T就变成了某个数据类型

第八章

string类

赋值

1
2
3
4
5
6
7
8
9
10
string s1("Hello");
cout <<s1.length()<<endl;//string类型长度输出
cout<<s1<<endl;
string s2(8,'x');//s2是8个x
cout<<s2<<endl;
string month="march";//直接赋值
cout << month<<endl;
string s;
s='n';//可以单个赋值
cout<<s<<endl;

string的复制

1
2
3
4
5
string s1("Hello"),s3;//直接复制
s3.assign(s1);
cout<<s3<<endl;
string s1("Hello"),s2,s3;
s3.assign(s1,2,3);//从s1的第2个复制3个字符,2形同下标

读取string的字符

1
2
s[0]//不会检测 ,可能会越界
s.at(0)//越界编译不会出错,但结果会提示出错

string连接

1
2
3
4
5
6
7
string s1("Hello"),s2("morning");
s1+=s2;//直接连接
cout<<s1<<endl;
s1.append(s2);//append连接
cout<<s1<<endl;

s2.append(s1,3,s1.size());//从s1的第3个复制s1.size()在s2的尾部

比较string

可以直接比较用bool类型记录结果

1
2
3
4
5
6
string s1("hello"),s2("hello"),s3("hell");
int f1=s1.compare(s2);//0 hello==hello
int f2=s1.compare(s3);//1 hello>hell
int f3=s3.compare(s1);//-1 hell<hello
int f4=s1.compare(1,2,s3,0,3);//-1el<hell 数字是代表下标
int f5=s1.compare(0,s1.size(),s3);//1 hello>hell第一个数是下标,第二个数字是s1比较的数量

子串

1
2
3
string s1("hello world"),s2;
s2=s1.substr(4,5);//下标4开始的5个字符
cout<<s2<<endl;//o wor

搜索find()

1
2
3
4
5
6
7
8
string s1("hello worlld");
cout<<s1.find("ll")<<endl;//2
cout<<s1.find("abc")<<endl;//4294967295正序查找没有的话出现一个很大的数
cout<<s1.rfind("ll")<<endl;//9逆序查找
cout<<s1.find_first_of("abcde")<<endl;//1 abcde中第一个字符的下标位置
cout<<s1.find_last_of("abcde")<<endl;//11 abcde中最后一个字符下标位置
cout<<s1.find_first_not_of("abcde")<<endl;//0在字符串中不是abcde的下标位置
cout<<s1.find_last_not_of("abcde")<<endl;//10逆序在字符串中不是abcde的下标位置

删除string元素

1
s1.erase(5)//会去掉下标5之后的字符

替换string元素

1
2
s1.replace(2,3,"hahah")//将s1下标为2到3的字符换成hahah
s1.replace(2,3,"hahah",1,2)//将s1下标为2到3的字符换成hahah的下标1开始的2个字符

插入string元素

1
2
s1.insert(5,s2)//将s2插入下标5的位置
s1.insert(2,s2,5,3)//将s2中下标5开始的3个字符插入s1下标2的位置

成员函数

c_str()

1
2
string s1("hello world");
printf("%s\n",s1.c_str());//s1.c_str()返回传统的const char*类型字符串,且该字符串以\0结尾

data()

1
2
string s1("hello world");
const char*p1=s1.data();//s1.data()返回char*类型的字符串,对s1的修改可能会使p1出错

STL库(一)

容器:可容纳各种数据类型的通用数据结构,是类模板
迭代器:可用于依次存取容器中的元素,类似于指针
算法:用来操作容器中的元素的函数模板

容器

1.顺序容器 vector动态数组 ,deque双向队列,list双向链表
2.关联容器set multset map multmap
3.容器适配器stack queue priority_queue

顺序容器

vector动态数组

头文件:
常数时间尾部性能最佳

deque双向队列

头文件:
随机存取任何元素常数时间,但次于vector,两端删减性能最佳
head头 tail尾,空元素

list双向链表

头文件
元素不能在内存不连续存放,在任何位置都能常数时间,不支持随机存取

关联容器

元素是排序的
插入任何元素,都是按相应的排序规则来确定其位置
在查找时具有非常好的性能
通常以平衡二叉树实现,时间logN

set/multiset

头文件
set不允许相同的元素,multiset允许相同的元素

map/multimap

头文件:
一个名为first另一个名为second,multimap允许相同的first值

容器适配器

stack

头文件:
栈,是项的有限序列只能修改删除检索最佳插入的项后进后出

queue

头文件
队列,插入只能从尾部,删除修改检索只能在头部进行先进先出

priority_queue

头文件
优先级队列,最高优先级的元素总是第一个出列

顺序容器和关联容器中都有的成员函数
begin 返回指向容器中第一个元素的迭代器
end 返回指向容器中最后一个元素后面的位置的迭代器
rbegin返回指向容器中最后一个元素的迭代器
rend返回指向容器中第一个元素前面位置的迭代器
erase 从容器中删除一个或几个元素
clear 从容器中删除所有元素

顺序容器的常用成员函数
front 返回容器中第一个元素的引用
back 返回容器中最后一个元素的引用
push_back 在容器末尾增加新元素
pop_back删除容器末尾的元素
erase 删除迭代器指向的元素(可能会使该迭代器失效),或删除一个区间,返回那个元素的迭代器

STL库(二)

迭代器

用于指向顺序容器和关联容器的元素
迭代器的用法和指针类似
有const 和非const两种
通过迭代器可以读取它指向的元素
通过非const迭代器还能修改其指向的元素

定义迭代器

容器类名::iterator 变量名;
容器类名::const_iterator 变量名;//常量迭代器
访问迭代器指向的元素
*迭代器变量名
容器类名::reverse_iterator 变量;//反向迭代器

STL库(三)

所有的vector都适用于deque
list
特有的成员函数
push_front 在前面插入
pop_front删除前面的元素
sort 排序(list不支持stl的算法sort)
remove 删除和指定值相同的所有元素
unique 删除所有和前一个元素相同的元素(做到不重复需要unique之前需要sort)
merge合并两个链表,并清空被合并的那个
reverse 颠倒链表
splice在指定位置前面插入另一个链表中的一个或多个元素,并在另一个链表删除被插入的元素
lst1.splice(p1,lst2,p2,p3)//将[p2,p3)插入p1之前,并从lst2中删除[p2,p3)

第九章

set与multiset

iterator find:查找等于某个值的元素
iterator lower_bound:查找某个下界
iterator upper_bound:查找某个上界
equal_range: 同时查找上界和下界
int count:计算等于某个值的元素个数
void insert:插入某个元素或某个区间

map与multimap

1直接赋值,例如 mp[“Tom”]=0
2通过插入一个类型为 pair<Key, T> 的值,例如 mp.insert(pair<string,int>(“Alan”,100));
map<string, int>::iterator it;//迭代器
cout << iter->first << “ “ << iter->second << endl;//不能用iter.first
但是可以重载<<
template<class Key,class Value>
ostream&operator<<(ostream&o,const pair<Key,Value>&p)
{
o<<”(“<<p.first<<”,”<<p.second<<”)”;
}
cout<<*s;
//map专用

Stack

push 插入元素
pop 弹出元素
top 返回栈顶的元素的引用
queue
push 插入元素发生在尾部
pop 弹出元素对头
top 返回栈顶的元素的引用对头
back 返回栈顶的元素的引用尾部
priority_queue
保证优先级最大的在前面,保证最大的在前面
size 还有多少数
empty 是否空

算法

1不变序列算法

min 求两个对象中较小的1
max 求两个对象较大的
min_element求区间最小的1
max_element求区间最大的//1有点问题
for_each对区间每个元素都做这种操作
count计算区间等于某值的元素个数
count_if计算区间符合某种条件的元素个数
find在区间查找某值的元素
find_if区间符合某种条件的元素
find_end从区间查找另一个区间出现的最后一次位置
find_first_of从区间查找另一个区间出现的第一次的元素
adjacent_find从区间查找第一次出现连续两个相等元素的位置
search在区间查找另一个区间第一次出现的位置
search_n在区间查找第一次出现等于某值的连续n个元素
equal判断两个区间是否相等
mismatch逐个比较两个区间的元素,返回第一次发生不相等的位置
lexicographical_compare按字典比较两个区间的大小

2.变值算法

for_each 对区间中的每个元素都做某种操作
copy复制一个区间到别处
copy_backward复制一个区间到别处但目标区前是从后往前被修改的
transform将一个区间的元素变形后拷贝到另一个区间//迭代器
swap_ranges交换两个区间的内容
fill用某个值填充区间
fill_n用某个值代替区间的n个元素
generate用某个操作的结果填充区间
generate_n用某个操作的结果替换区间中的n个元素
replace将区间中某个值替换为另一个值
replace_if将区间中符合某种条件的值替换成另一个值
replace_copy将一个区间拷贝到另一个区间,拷贝时某个值要换成新值拷过去
replace_copy_if将一个区间拷贝到另一个区间,拷贝时符合某种条件的值要换成新值拷过去

accumulate(first,last,累加的数);求和

3删除算法

remove 删除区间中等于某个值的元素
unique删除区间中连续相等的元素,只留下一个

4变序算法

random_shuffle(first,last);随机打乱
reverse 颠倒区间次序
next_permutation将区间改为下一个排列
prev_permutation将区间改为上一个排列//可以list

5排序算法

随机访问迭代器 不支持关联容器和list
sort()从小到大排序

6有序区间算法

要求是从小到大排好的随机访问迭代器 不支持关联容器和list
binary_search判断区间是否又某个元素
lower_bound查找最后一个不小于某个值的元素的位置
upper_bound查找第一个大于某个值的元素位置
equal_range同时获取upper_bound,lower_bound

7bitset

bitset&set();全部为1
bitset&set(size_t pos,bool val=true);设置某位
bitset&reset();全部为0
bitset&reset(size_t pos);某位设为0
bitset&flip();全部翻转
bitset&flip(size_t pos)翻转某位

第十章

c++11的新特性

  1. 数组,容器可以直接用花括号初始化.

  2. auto关键字
    迭代器的时候可以用auto

  3. decltype关键字
    返回数据类型

  4. 智能指针shared_ptr
    头文件
    会自动delete,不能是指针数组

  5. 空指针nullpr
    转化bool等于false

  6. 基于范围for循环
    int ary[]={1,2,3,4,5};
    for(int &e:ary)
    e*=10//输出10,20,30,40,50*

  7. *右值引用
    &&是右值引用
    减少进行深拷贝的次数

  8. 无序容器(哈希表)
    头文件
    用法和map一样,效率更高

  9. 正则表达式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    头文件<regex>
    regex reg("b.?p.*k")
    regex_match//匹配成功1匹配失败0
    10。lambda表达式
    [外部变量访问方式说明符](参数表)->返回值类型
    {
    语句组
    }
    [=]以传值的方式使用外部变量
    [] 不使用任何外部变量
    [&]以引用的方式使用所有的外部变量
    [x,&y]x传值,有引用
    [=,&x,&y]x,y引用,其他传值
    [&,x,y]x,y传值,其他引用

强制转换

static_cast reinterpret_cast
const_cast dynamic_cast
1.static_cast
用于整型,实数型,字符型
static_cast<类型>(数)
2.reinterpret_cast
不同类型的指针之间的转换,不同类型的引用之间的转换
3.const_cast
去除const的转换
4.dynamic_cast
将多态基类的指针或引用强制转换为派生类的指针和引用
必须是多态

异常处理

try{throw 类型}处理
catch(参数){}
多个catch
如果程序异常没有被catch捕获,程序崩溃
catch(…){}属于任何异常
exception类
bad_typeid
转换异常
bad_cast
多态基类指针转换异常
bad_alloc
在用new运算符进行动态内存分配时,没有足够的内存
ios_base::failure

bad_error–>out_of_range
下标越界

易错点

继承

可以将子类赋值给父类,在继承时注意需要加public才能让子类继承父类,不然父类就成了私有类了

1
2
3
4
5
6
class C :public A {
public:
virtual void Print() {
cout << "Class C" << endl;
}
};

多态

override是在c++11的时候加的在c++中可以全用virtual也可以子类在函数名后加override

1
2
3
4
5
6
7
8
9
10
11
12
 class B :public A {
public:
void Print() override {
cout << "Class B" << endl;
}
};
class C :public A {
public:
virtual void Print() {
cout << "Class C" << endl;
}
};

用子类指针调用基类

其一是强制转换但可以是不安全的

个人觉得其二还是有很大局限性的,需要基类要虚函数
其二是用dynamic_cast
将多态基类的指针或引用强制转换为派生类的指针和引用
必须是多态