STL诞生
- 可重复利用
- c++面向对象和泛型编程思想,目的就是重复性的提升
- 大多数情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作
- 为了建立数据结构和算法的一套标准,诞生了STL
STL基本概念
- STL标准模板库(standard Template Library)
- DTL从广义上分为 容器(container)算法(algorithm)迭代器(iterator)
- 容器和算法之间通过迭代器进行无缝链接
- STL几乎所有的代码都采用了模板或者模板函数
STL六大组件
- STL大体分为六大组件,分别为:容器,算法,迭代器,仿函数,适配器,空间配置器
- 容器:各种数据结构,如vector,list,deque,set,map等数据结构
- 算法:各种常用算法,如sort,find,copy,each等
- 迭代器:扮演了容器和算法之间的胶合剂
- 仿函数:行为类似函数,可作为算法的某种策咯
- 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西
- 空间适配器:负责空间的配置与管理
STL中容器,算法,迭代器
容器:放东西用的
STL容器就是将运用最广泛的一些数据结构实现出来
常用的数据结构有:数组,链表,树,栈,队列,集合,映射表等
这些容器分为序列式容器和关联式容器两种:
- 序列式容器:强调值的排列,序列式容器中的每个元素均有固定的位置
- 关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系
算法:问题的解法(algorithms)
算法分为质变算法和非质变算法
- 质变算法:是指运算过程中会更改区间内元素的内容,例如拷贝,替换,删除等
- 非质变算法:是指运算过程中,不会更改区间内的全部内容,例如查找,计数,遍历,寻找极值等
迭代器:容器算法之间的粘合剂
提供一种方法,使之能够依序寻访某个容器中所含的元素,而又无需暴漏该容器的内部表示方式
每个容器都有自己的 专属迭代器
迭代器的使用非常类似于指针
迭代器种类:
常用的容器中迭代器种类为双向迭代器,和随机访问迭代器
容器算法迭代器的初步认识
vector存放内置数据类型
- 容器:vector
- 算法:for_each
- 迭代器:vector<int>::iterator
#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
void myprint(int val)
{
cout<<val<<endl;
}
void test01()
{
//创建了一个vector
vector<int> v;
//向容器中插入数据
v.push_back (10);
v.push_back (20);
v.push_back (30);
v.push_back (40);
v.push_back (50);
//通过迭代器访问容器中的数据
vector<int>::iterator itBegin=v.begin ();//v.begin()起始迭代器,指向容器中第一个元素
vector<int>::iterator itend=v.end ();//结束迭代器,指向容器中最后一个元素的下一个位置
//第一种遍历方式
while(itBegin !=itend )
{
cout<<*itBegin <<endl;
itBegin ++;
}
cout<<"///"<<endl;
//第二种遍历方式
for(vector<int>::iterator it=v.begin ();it!=v.end ();it++ )
{
cout<<*it<<endl;
}
cout<<"//"<<endl;
//第三种遍历 利用stl中的遍历算法 for_ezch
for_each(v.begin (),v.end (),myprint);//利用回调
}
int main()
{
test01();
}
for_each()底层实现
vector中存放自定义数据类型
看代码:
#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class animal
{
public:
animal(string name,int age)
{
this->_name =name;
this->_age =age;
}
string _name;
int _age;
};
void test01()
{
//创建一个自定义类型的容器
vector<animal >v;
//向容器中添加数据
animal p1("aaa",10);
animal p2("bbb",20);
animal p3("ccc",30);
animal p4("ddd",40);
animal p5("eee",50);
v.push_back (p1);
v.push_back (p2);
v.push_back (p3);
v.push_back (p4);
v.push_back (p5);
//遍历容器中的数据
//注意*it完成解引用后市寄存器的类型,也就是animal类型
for(vector<animal>::iterator it=v.begin ();it!=v.end();it++)
{
cout<<"姓名: "<<(*it)._name <<"年龄"<<(*it)._age <<endl;
//it是一个指针,通过箭头也可以访问
cout<<"姓名:"<<it->_name <<"年龄"<<it->_age <<endl;
}
}
//存放自定义类型的指针
void test02()
{
//创建一个自定义类型的容器
vector<animal* >v;
//向容器中添加数据
animal p1("aaa",10);
animal p2("bbb",20);
animal p3("ccc",30);
animal p4("ddd",40);
animal p5("eee",50);
v.push_back (&p1);
v.push_back (&p2);
v.push_back (&p3);
v.push_back (&p4);
v.push_back (&p5);
//遍历容器
for(vector<animal *>::iterator pit=v.begin ();pit!=v.end();pit++)
{
//(*pit)是animal类型的指针
cout<<"姓名:"<<(*(*pit))._name <<"年龄:"<<(*(*pit))._age <<endl;
cout<<"姓名:"<<(*pit)->_name <<"年龄:"<<(*pit)->_age <<endl;
}
}
int main()
{
//test01();
test02();
}
vector容器嵌套(类似于二维数组)
#include<iostream>
#include<vector>
using namespace std;
void test01()
{
vector<vector<int>> v;
//创建 小容器
vector <int> v1;
vector <int> v2;
vector <int> v3;
vector <int> v4;
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);
//通过大容器来遍历所有数据,(*it)是容器---vector<int>
for(vector <vector<int> > ::iterator it=v.begin ();it!=v.end();it++)
{
for(vector <int>::iterator sit=(*it).begin ();sit!=(*it).end();sit++)
{
cout<< *sit <<" ";
}
cout<<endl;
}
}
int main()
{
test01();
}
string容器
本质:
- string是c++风格的字符串,而string 本质上是一个类
string和char *的区别:
- cha r* 是一个指针
- string是一个类,类的内部封装了char*,管理这个字符串,是一个char *型的容器
特点:
- string 内部封装了很多成员方法
- 例如:查找find(),拷贝copy(),删除delete,替换replace ,插入insert
- string 管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责
string 构造函数
构造函数原型
- string() //创建一个空的字符串,例如string str;
- string (const char *s) //使用字符串s 初始化
- string(const string &str)//使用一个string对象初始化另外一个string 对象
- string(int n,char c)//使用n个字符c初始化
#include<iostream>
#include<vector>
#include<string>
using namespace std;
void test01()
{
string s1;//默认构造
const char*str="hello world";
string s2(str);
cout<<"s2:"<<s2<<endl;
string s3(s2);
cout<<"s3:"<<s3<<endl;
string s4(10,'a');
cout<<"s4:"<<s4<<endl;
}
int main()
{
test01();
}
strint 的赋值操作
#include<iostream>
#include<vector>
#include<string>
using namespace std;
void test01()
{
string str1;
str1="hello world";
cout<<"str1="<<str1<<endl;
string str2;
str2=str1;
cout<<"str2="<<str2<<endl;
string str3;
str3='a';
cout<<"str3="<<str3<<endl;
string str4;
str4.assign ("hello nihao");
cout<<"str4="<<str4<<endl;
string str5;
str5.assign ("hello nihao",5);
cout<<"str5="<<str5<<endl;
string str6;
str6.assign (str5);
cout<<"str6="<<str6<<endl;
string str7;
str7.assign (10,'w');
cout<<"str7="<<str7<<endl;
}
int main()
{
test01();
}
string 字符串拼接
实现在字符串末尾拼接字符串
#include<iostream>
#include<vector>
#include<string>
using namespace std;
void test01()
{
string str1="我";
str1+="爱看剧";
cout<<"str1="<<str1<<endl;
str1+=':';
cout<<"str1="<<str1<<endl;
string str2="wangzhe";
str1+=str2;
cout<<"str1="<<str1<<endl;
string str3="i ";
str3.append ("love ");
cout<<"str3="<<str3<<endl;
str3.append ("you too",3);
cout<<"str3="<<str3<<endl;
str3.append (str2);
cout<<"str3="<<str3<<endl;
str3.append (str2,4,3);
cout<<"str3="<<str3<<endl;
}
int main()
{
test01();
}
string 查找和替换
- 查找:查找指定字符串是否存在
- 替换:在指定的位置替换字符串
#include<iostream>
#include<vector>
#include<string>
using namespace std;
//查找
void test01()
{
string str1="abcdefghijk";
int pos=str1.find("de");//默认为0位置
if(pos==-1)
{
cout<<"未找到字符串"<<endl;
}
else
{
cout<<"pos="<<pos<<endl; //3 下标从0开始 没有返回-1
}
pos=str1.rfind ("de");
cout<<"pos="<<pos<<endl;
//rfind和find的区别,,rfind从右往左查找,fin是从左往右查找
}
void test02()
{
string str1="abcdefg";
//从1号位置起三个字符串替换为1111
str1.replace (1,3,"1111");
cout<<"str1="<<str1<<endl;
}
int main()
{
test01();
test02();
}
总结:
- find查找从左往右,rfind相反
- find查找到字符串后返回查找的第一个字符的位置,找不到返回-1
- replace在替换时,要指定从那个位置开始,多少个字符,替换成什莫样的字符串
string 字符串比较
字符串比较是按照字符串的ascll码进行比较
= 返回0
>返回1
<返回-1
#include<iostream>
#include<vector>
#include<string>
using namespace std;
//查找
void test01()
{
string str1="zello";
string str2="hello";
if(str1.compare (str2)==0)
{
cout<<"str1==str2"<<endl;
}
else if(str1.compare (str2)>0)
{
cout<<"str1>str2"<<endl;
}
else
{
cout<<"str1<str2"<<endl;
}
}
int main()
{
test01();
//test02();
}
主要是比较相等
string中单个字符存取
#include<iostream>
#include<vector>
#include<string>
using namespace std;
//查找
void test01()
{
string str="hello";
cout<<"str="<<str<<endl;
//通过[]访问单个字符
//通过at访问单个字符
for(int i=0;i<str.size ();i++)
{
cout<<str[i]<<" ";
}
cout<<endl;
for(int i=0;i<str.size ();i++)
{
cout<<str.at(i)<<" ";
}
cout<<endl;
//修改单个字符
str[0]='x';
cout<<"str="<<str<<endl;
str.at(1)='y';
cout<<"str="<<str<<endl;
}
int main()
{
test01();
//test02();
}
string 中的插入和删除
注:插入删除的起始下标都是从0开始的
string字串
#include<iostream>
#include<vector>
#include<string>
using namespace std;
//查找
void test01()
{
string str="helloworld";
string sub=str.substr(1,2);//没有参数的话,默认截取全部
cout<<"sub="<<sub<<endl;
}
//实际操作
void test02()
{
string email="fooooood@163.com";
//从邮箱地址中获取用户信息
int pos=email.find("@");//9
string usname=email.substr (0,pos);
cout<<"usname:"<<usname<<endl;
}
int main()
{
//test01();
test02();
}