目录
一、string类
1、构造字符串
2、string类输入
3、使用字符串
二、智能指针模板
1、作用
2、指针模板的使用
3、智能指针模板注意事项
三、标准模板库
1、vector
2、deque
3、stack
4、queue
5、list容器
6、set/multiset
7、map
四、函数对象
1、什么是函数对象
2、谓词
3、内建函数对象
(1)算术仿函数
(2)关系仿函数
(3)逻辑仿函数
五、算法
1、遍历算法
2、查找算法
3、排序算法
4、拷贝和替换算法
5、算术生成算法
6、集合算法
string one("Lottery Winner!");//one=Lottery Winner!
string two(20,'$');//two=$$$$$$$$$$$$$$$$$$$$
string three(one);//three=Lottery Winner!
three[0]='P';three=Pottery Winner!
string four;
two="sorry! That was ";
four=two+three;//four=sorry! That was Pottery Winner!
char alls[]="All's well that ends well";
string five(alls,20);//five=All's well that ends
string six(alls+6,alls+10);//six为alls的第六到第十的字符即:six=well
string seven(&five[6],&five[10]);//seven为alls的第六到第十的字符即:six=well
string eight(four,7,16);//eight为four的第七开始,输出的十六个字符:eight=That was Pottery
string stuff;
cin>>stuff;
getline(cin,stuff);
getline(stuff,':')//':'符号为边界
string类的getline版本读取结束标志:
①遇到文件尾,fail和eof返回true
②遇到分界字符,比如上面的‘:’
③读取到的字符数达到最大值,即string::npos(一般为unsigned int的最大值)和可分配的内存字节数中较小的一个
可以将string对象和C-风格字符串进行比较,另外,还可以通过line()和size()函数返回对象的字符串,find函数搜索给定的子字符串或字符
string snake1("cobra");
string snake1("coral");
char snake3=("anaconda");
if(snake1
使用new开辟内存空间后将地址赋给指针,并且在指针过期的时候需要将对应内存释放,即使用delete,不过有时候忘记释放将导致内存泄漏。使用智能指针模板可以避免这种情况,在指针过期时,将自动调用模板的折构函数,其中包含delete释放内存。这意味着将new返回的地址赋给这些对象后,无需记住释放内存。有三智能指针模板(auto_ptr,unique_ptr和shared_ptr).
使用智能指针需要包含头文件memory,再使用通常的模板语句来实例化所需类型指针。另外,智能指针模板位于名称空间std中。
auto_ptr pd(new double);
auto_ptr ps(new string);
auto_ptr ps(new string("I reigned longly as a cloud."));
auto_ptr vocation;
vocation=ps;
使用上述赋值语句,将使得ps和vocation指向同一个string对象,这将导致删除同一个对象两次(ps过期以及vocation过期时),避免此类问题的方法如下:
①定义赋值运算符,使之执行深复制,将两个指针指向不同的对象,其中一个是另一个的对象副本。
②建立所有权概念,即一个对象只能有一个智能指针拥有它,这样只有拥有对象的智能指针的构造函数删除对象。赋值操作将转让所有权。这是auto_ptr以及unique_ptr的策略
③创建智能更高的指针,可以统计对象的智能指针数(引用计数),赋值+1,过期-1,当最后一个指针过期时,才调用delete。这是shared_ptr的策略。
unique_ptrdemo(const char *s)
{
unique_ptr temp(new string(s));
return temp;
}
unique_ptrps;
ps=demo("Uniquely special");//返回的temp是个临时变量,再转移所有权后会被销毁
//不过unique_ptr禁止这类语句
unique_ptr ps(new string("auto"));
unique_ptr pd;
//即允许是一个临时变量,不允许存在一段时间
STL(标准模板库)提供了一组表示容器,迭代器,函数对象和算法的模板。
容器:类似于数组的存储单元,可以存储各种数据(但是容器只能存储同一变量的值)
迭代器:用来遍历容器的对象,与遍历数组的指针类似
函数对象:函数的对象,可以是类对象或者函数指针
STL使得能够构造各种容器(包括数组,队列和链表)和执行各种操作(包括搜索,排序和随机排列)
vector使用需要包含头文件
,使用 ①构造函数
vector
v;//采用模板 vector(v.begin(),v.end());//将v[begin(),end()]区间中的元素拷贝给本身
vector(n,elem);//将n个elem拷贝给本身
vector(const vector &vec)//拷贝构造函数
②赋值操作
vector& operator=(const vector &vec);//重载等号运算符
assign(beg,end);
assign(n,elem);
③容量及大小
empty();//判断容器是否为空
capacity();//容器的容量
size();//返回容器中元素的个数
resize(int num);//重新定义容器长度为num,若变长,以默认值填充新位置,变短则删除
resize(int num,elem);//elem为默认值
④插入与删除
push_back();//尾部插入ele
pop_back();//删除最后一个元素
insert(const_iterator pos,ele);//在pos插入指定元素ele
insert(const_iterator pos,int count,ele);//在pos插入count个元素ele
erase(const_iterator pos);//删除指定位置元素
erase(const_iterator start,const_iterator end);//删除从start到end的内容
clear();//删除所有
⑤数据获取
at(int idx);//返回索引idx所指的数据
operator[];//返回索引idx所指的数据
front();//返回第一个数据
back();//返回最后一个数据
⑥互换容器
swap(vec);//将vec与本身元素互换
⑦预留空间
reserve(int len);//预留长度
#include
#include
#include
#include
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
//定义类用于存放名字及年龄
class Person
{
public:
Person(string name,int age)
{
this->m_name=name;
this->m_age=age;
}
string m_name;
int m_age;
};
//打印数据
void myPrint(int val)
{
cout< v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
vector::iterator itBegin=v.begin();
vector::iterator itEnd=v.end();
while(itBegin!=itEnd)
{
cout<<*itBegin<::iterator it=v.begin();it!=v.end();it++)
{
cout<<*it<v;
Person P1("aaa",44);
Person P2("bbb",55);
Person P3("ccc",66);
Person P4("ddd",77);
Person P5("eee",88);
v.push_back(P1);
v.push_back(P2);
v.push_back(P3);
v.push_back(P4);
v.push_back(P5);
for(vector::iterator it=v.begin();it!=v.end();it++)
{
cout<<"姓名:"<<(*it).m_name<<" 年龄:"<<(*it).m_age<m_name<<" 年龄:"<m_age<v;
Person P1("aaa",44);
Person P2("bbb",55);
Person P3("ccc",66);
Person P4("ddd",77);
Person P5("eee",88);
v.push_back(&P1);
v.push_back(&P2);
v.push_back(&P3);
v.push_back(&P4);
v.push_back(&P5);
for(vector::iterator it=v.begin();it!=v.end();it++)
{
cout<<"姓名:"<<(*it)->m_name<<" 年龄:"<<(*it)->m_age<m_name<<" 年龄:"<m_age<>v;
//创建小容器
vectorv1;
vectorv2;
vectorv3;
vectorv4;
for(int i=0;i<4;i++)
{
v1.push_back(i+1);
v2.push_back(i+2);
v3.push_back(i+3);
v4.push_back(i+4);
}
//将小容器插入到大的容器
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
v.push_back(v4);
for(vector>::iterator it=v.begin();it!=v.end();it++)
{
for(vector::iterator it1=(*it).begin();it1!=(*it).end();it1++)
{
cout<<*it1<<' ';
}
cout<
双端数组
与vector区别:
①vector对于头部的插入删除效率低,数据量越大,效率越低
②deque相对而言,对头部的插入删除速度回比vector快
③vector访问元素时的速度会比deque快,这和两者内部实现有关其使用:
①构造函数
deque
deqT; //默认构造形式
deque(beg, end); //构造函数将[beg, end)区间中的元素拷贝给本身。
deque(n, elem); //构造函数将n个elem拷贝给本身。
deque(const deque &deq); //拷贝构造函数②赋值
deque& operator=(const deque &deq); //重载等号操作符
assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem); //将n个elem拷贝赋值给本身。③容器及大小
deque.size(); //返回容器中元素的个数
deque.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
如果容器变短,则末尾超出容器长度的元素被删除。
deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。④插入与删除:
两端插入操作:
push_back(elem); //在容器尾部添加一个数据
push_front(elem); //在容器头部插入一个数据
pop_back(); //删除容器最后一个数据
pop_front(); //删除容器第一个数据
指定位置操作:
insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值。
clear(); //清空容器的所有数据
erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos); //删除pos位置的数据,返回下一个数据的位置。⑤索引
at(int idx); //返回索引idx所指的数据
operator[]; //返回索引idx所指的数据
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素⑥排序
sort(iterator beg, iterator end) //对beg和end区间内元素进行排序
stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口(堆栈)
①构造函数:
stackstk; //stack采用模板类实现, stack对象的默认构造形式
stack(const stack &stk); //拷贝构造函数
②赋值操作:
stack& operator=(const stack &stk); //重载等号操作符
③数据存取:
push(elem); //向栈顶添加元素
pop(); //从栈顶移除第一个元素
top(); //返回栈顶元素
④大小操作:
empty(); //判断堆栈是否为空
size(); //返回栈的大小
queue是一个先进先出的数据结构
①构造函数:
queueque; //queue采用模板类实现,queue对象的默认构造形式
queue(const queue &que); //拷贝构造函数
②赋值操作:
queue& operator=(const queue &que); //重载等号操作符
③数据存取:
push(elem); //往队尾添加元素
pop(); //从队头移除第一个元素
back(); //返回最后一个元素
front(); //返回第一个元素
④大小操作:
empty(); //判断堆栈是否为空
size(); //返回栈的大小
将数据进行链式存储(链表)
①构造函数
listlst; //list采用采用模板类实现,对象的默认构造形式:
list(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem); //构造函数将n个elem拷贝给本身。
list(const list &lst); //拷贝构造函数。②赋值
assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
assign(n, elem); //将n个elem拷贝赋值给本身。
list& operator=(const list &lst); //重载等号操作符
swap(lst); //将lst与本身的元素互换。③容量与大小
size(); //返回容器中元素的个数
empty(); //判断容器是否为空
resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。
resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。④插入与删除1
push_back(elem);//在容器尾部加入一个元素
pop_back();//删除容器中最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//从容器开头移除第一个元素
insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
clear();//移除容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
erase(pos);//删除pos位置的数据,返回下一个数据的位置。
remove(elem);//删除容器中所有与elem值匹配的元素。⑤数据获取
front(); //返回第一个元素。
back(); //返回最后一个元素。⑥反转和排序
reverse(); //反转链表
sort(); //链表排序
所有元素在插入时会自动排序(底层使用二叉树)
两者差别:
set不允许容器中有重复的元素
multiset允许容器中有重复的元素①构造:
set
st; //默认构造函数:
set(const set &st); //拷贝构造函数
②赋值:
set& operator=(const set &st); //重载等号操作符③大小及切换
empty();//判断容器是否为空
swap(st); //交换两个集合容器size(); //返回容器中元素的数目
④插入和删除
insert(elem); //在容器中插入元素。
clear(); //清除所有元素erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem); //删除容器中值为elem的元素。⑤查找和统计
find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key); //统计key的元素个数
map所有元素都是pair,pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)所有元素都会根据元素的键值自动排序。
map和multimap区别:
map不允许容器中有重复key值元素
multimap允许容器中有重复key值元素①构造与赋值
构造:
mapmp; //map默认构造函数:
map(const map &mp); //拷贝构造函数
赋值:
map& operator=(const map &mp); //重载等号操作符②大小与切换
size(); //返回容器中元素的数目
empty(); //判断容器是否为空
swap(st); //交换两个集合容器③插入与删除
insert(elem); //在容器中插入元素。
clear(); //清除所有元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(key); //删除容器中值为key的元素。④查找与统计
find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key); //统计key的元素个数
通过重载()运算符,使得使用时方式类似函数调用,也叫仿函数
特点:
①函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值
②函数对象超出普通函数的概念,函数对象可以有自己的状态
③函数对象可以作为参数传递
class Linear
{
private:
double slope;
double y0;
public:
Linear(double s1_=1,double y_=0):slope(s1_),y0(y_){}
double operator()(double x){return y0+slope*x;}
}
Linear f1;
Linear f2(2.5,10.0);
double y1=f1(12.5);//y1=0+1*12.5
double y2=f2(0.4);//y2=10.0+0.4*2.5
返回类型为bool的仿函数叫做谓词,如果operator()接受一个参数,那么叫做一元谓词
两个参数,叫做二元谓词
STL内建了一些函数对象:算术、关系、逻辑仿函数,需要包含头文件functional
template
T plus //加法仿函数
templateT minus //减法仿函数
templateT multiplies //乘法仿函数
templateT divides //除法仿函数
templateT modulus //取模仿函数
templateT negate //取反仿函数
template
bool equal_to //等于
templatebool not_equal_to //不等于
templatebool greater //大于
templatebool greater_equal //大于等于
templatebool less //小于
templatebool less_equal //小于等于
template
bool logical_and //逻辑与
templatebool logical_or //逻辑或
templatebool logical_not //逻辑非
算法主要是由头文件
组成。
①是所有STL头文件中最大的一个,范围涉及到比较、 交换、查找、遍历操作、复制、修改等等
②体积很小,只包括几个在序列上面进行简单数学运算的模板函数
③定义了一些模板类,用以声明函数对象。
for_each(iterator beg, iterator end, _func); //遍历容器
transform(iterator beg1, iterator end1, iterator beg2, _func);//搬运容器到另一个容器中(搬运的目标容器需要提前开辟空间,否则无法正常搬运)
find(iterator beg, iterator end, value);//查找元素
find_if(iterator beg, iterator end, _Pred);//按条件查找元素(条件在_Pred中,可以是函数或者谓词(返回bool))
adjacent_find(iterator beg, iterator end);//查找相邻重复元素,返回第一个位置迭代器
bool binary_search(iterator beg, iterator end, value);//查找指定元素是否存在
count(iterator beg, iterator end, value);//统计元素个数
count_if(iterator beg, iterator end, _Pred);//按照条件统计数据
sort(iterator beg, iterator end, _Pred);//按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
random_shuffle(iterator beg, iterator end);//指定范围内随机调整次序
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);//两容器合并,并加到另一个容器中(dest)
reverse(iterator beg, iterator end);//将容器1元素进行反转
copy(iterator beg, iterator end, iterator dest);//将指定元素复制到另一个元素中
replace(iterator beg, iterator end, oldvalue, newvalue);//将容器中指定范围的旧元素修改为新元素
replace_if(iterator beg, iterator end, _pred, newvalue);//将满足条件的元素替换成新元素
swap(container c1, container c2);//互换两个容器的元素
包含头文件numeric
accumulate(iterator beg, iterator end, value);//计算容器元素总和
fill(iterator beg, iterator end, value);//向容器中添加元素
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);求两个容器的交集
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);//两个容器的并集
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);//两个容器的差集
C++的学习笔记持续更新中~
要是文章有帮助的话
就点赞收藏关注一下啦!
感谢大家的观看
欢迎大家提出问题并指正~