STL(标准模板库):是C++标准程序库的核心,是一个泛型程序库,提供了一系列软件解决方案。利用先进,高效的算法来管理数据。从程序员角度看,STL是由一些可适应不同需求的群集类别和一些能够在这些数据群集上运作的算法构成。STL内部的所有组件都由template构成,所以其元素可以是任意型别。
# include <iostream> # include <algorithm>//算法的头文件 using namespace std; template <class T>//template:模板 <class T> 类型参数表 T Max(T a,T b)//函数模板经过参数实例化后称为模板函数 { return a>b?a:b; } int main () { cout<<Max(2,5)<<endl; cout<<Max('t','a')<<endl; } template<class T1,class T2> void fn(T1 a, T2 b)//两种不同参数类型的模板函数 { cout << a << " " << b << endl; } void main() { fn('a', 5); }
STL组件:最关键的是容器、算法、迭代器
STL的基本观念就是将数据和操作分离。数据由容器类别加以管理,操作则由可定制的算法定义之。迭代器在二者之间充当粘合剂,使任何算法都可以和任何容器交互运作。
容器(Containers)
容器:用来管理某类对象的集合,容纳特定数据结构对象的集合,STL容器是将最常用的一些数据结构实现出来,包含了许多数据结构,如:vector,queue,stack...string也可以看作是一个容器。
分类:容器用来管理一组元素,为了适应不同需要,STL根据数据在容器中排序的特性,容器可分为序列式容器和关联式容器。
序列式容器:可序群集,其中每个元素都有固定的位置----取决于插入时机和地点,与元素的值没有关系,如果你以追加方式对一个群集置入n个元素,它们的排列次序将与置入次序一致。如:vector,deque,list
关联式容器:已序群集,元素位置取决于特定的排序准则,和插入顺序无关。如果你将n个元素置于这样的群集中,它们的位置区别于元素值,和插入次序无关。STL提供了4个这样的容器:set,map,multiset,multimap。
关联式容器也可被视为特殊的序列式容器,因为已序群集正是根据某个排序准则排列而成。
算法(Algorithms)
算法:用来处理群集内的元素,它们可以出于不同的,䣌而搜索,排序,修改,使用那些元素。是一种应用在容器上以各种方法处理其内存的行为或功能,如sort(排序),copy(拷贝)...,算法由模板函数体现,这些函数不是容器类的成员函数,是独立的函数,它们可以用于STL容器,也可以用于普通的C++函数
sort:排序函数
# include <iostream> # include <algorithm> using namespace std; int main () { int a[]={1,3,2,5,4,7,6,9,8,0}; int n=sizeof (a)/sizeof(a[0]); sort(arr,arr+n);//默认从小到大进行排序 sort(a,a+n,greater<int>());//从大到小排序 sort(a,a+n,less<int>());//从小到大排 }
copy:复制函数
void main() { int a[5] = { 1,2,3,4,5 }; int b[5]; copy(a, a + 5, b);//将数组a,下标0~4共五个元素复制到数组b中 copy(b, b + 5, ostream_iterator<int>(cout, ","));//将数组b输出出来,第三个参数用到了迭代器 } 也可以用for_each进行输出 void print(int n) { cout<<n<<" "; } void main () { int a[5]={1,2,3,4,5}; int b[5]; copy(a,a+5,b); for_each(b,b+5,print); }
find:查找函数,找到了返回位置信息,没有找到返回end
find()函数的调用形式是find(start,end,value)
start搜索的起点,end搜索的终点,要寻找的value值
容器的表示方法:find(a.begin(),a.end(),value);
数组的表示方法:find(a,a+length,value);
find_if():查找满足条件下的值
bool great5(int n) { return n > 5; } template<class T> class Less5 { public: bool operator()(T n) { return n < 5; } }; void main() { int a[] = { 1,2,3,4,5 }; int b[] = { 6,7,8,9,0 }; int n = sizeof(a) / sizeof(a[0]); int *p; p = find_if(a, a + n, great5); cout << *p << endl; p = find_if(a, a + n, Less5<int>()); cout << *p << endl; reverse(a, a + n);//反转 swap_ranges(a, a + 3, b);//数组a,a,a+3与数组b进行同范围的交换 cout<<count(a, a + 5, 2)<<endl;//计数a,a+5范围中2的个数 cout<<count_if(a, a + 5, Less5<int>())<<endl;//计算a,a+5满足条件下的个数 }
include:检测一个数组是否包含另一个数组
if (includes(a, a + 10, b, b + 5)) //一个数组是否包含另外一个数组 cout << "\n" << "sorted b members are included in a." << endl; else cout << "sorted a dosn`t contain sorted b!";
迭代器:用来在一个对象群集的元素上进行遍历动作。这个对象群集或许是个容器,或许是容器的一部分。迭代器的主要好处是,为所有容器提供了一组很小的公共接口,利用这个接口,某项操作就可以行进至群集内的下一个元素。每一种容器都提供了自己的迭代器,而这些迭代器了解该种容器的内部结构,所以能够知道如何正确行进。迭代器的接口和一般指针差不多。可将其看作是一个指向容器中元素的普通指针,用迭代器来访问容器中的元素,是它将算法和容器连接在一起,每个容器都有自己的迭代器,只有容器自己才知道如何访问自己的元素.
begin--指向第一个元素的迭代器
end --指向最后一个元素的下一个的迭代器
front--返回第一个元素
back--返回最后一个元素
assign --对vector中元素赋值
at --返回指定位置的元素值
resize -- 改变元素数量的大小
reserve --设置vector最小的元素容纳大小
clear ---清空
empty --空
size ---大小
capacity ---容量
insert ---插入
erase ----删除指定元素
push_back:在原有最后一个元素后插入
pop_back:删除最后一个元素
swap --交换两个vectorvoid main () { vector<int> vv; copy(istream_iterator<int>(cin),istream_iterator<int>(),back_insert_iterator<vector<int>>(vv));//第一个参数istream_iterator<int>(cin)输入迭代器·的指针 第二个参数istream_iterator<int>()不带参数表示如果当前输入不是int型视为非法输入,结束输入 。第三个参数back_insert_iterator<vector<int>>(vv)向vv数组最后插入迭代器 sort(vv.begin(),vv.end()); copy(vv.begin(),vv.end(),ostream_iterator<int>(cout," ")); cout<<endl; //istream_iterator输入流迭代器 }
Vector
vector:将其元素置于一个动态数组中加以管理。是一种动态数组,是基本数组的类模板,可用于代替C中的数组,能够存放各种类型的对象,能够增加和压缩数据。它支持随机存取,也就是说你可以利用索引值直接存取任何一个元素。在array尾部附加元素或移动元素非常迅速,但是在array中部或头部安插元素就比较费时,因为,为了保持原本的相对次序,插入点之后的所有元素都必须依次移动。
vector是一个类,有自己的构造函数,在vector类中定义了4种构造函数,分别如下操作:
vector<int> a;
vector<int>b(5,0);//初始化b中为5个0
vector<int>c(b);//用b数组堆a进行初始化
vector<int>d(m,m+5);
vector中大小和容量的问题
Size()告诉你容器中有多少个元素,没有告诉你容器为它所能容纳的元素分配了多少内存
capacity()容器在它已经分配的内存中可以容纳多少元素,是总共可以容纳的元素
resize(n)强制把容器改为容纳n个元素
reserve(n)强制容器把他的容量改为至少为n,提供的n不小于当前的大小,使用此函数不改变容器中对象的个数。
有了这个大小和容量的函数,可以让我们知道什么时候往容器插入元素将引起容器执行重新分配空间,而且可以知道什么时候插入会使指向容器的迭代器指针引用失效.
if(s.size<s.capacity())
{
s.push_back(5);//此句插入不会使指向这个容器的迭代器指针失效
}
vector的函数
vector还有以下函数:
capacity():返回重新分配空间前所能容纳的元素最大数量
reserve()如果容量不足扩大之
c.assign(n,elem):复制n个elem,赋值给c
c.assign(beg,end):将区间[beg,end]内的元素赋值为c
c.at(index):返回索引为index的元素,如果越界,则抛出异常
c[index]:返回索引为index的元素,不检查错误
c.front():返回第一个元素,不检查第一个元素是否存在
c.back():返回最后一个元素,不检查最后一个元素是否存在
c.insert(pos,elem):在pos位置上插入一个elem,并返回新元素位置
c.insert(pos,n,elem):在pos位置上插入n个elem,无返回值
c.insert(pos,beg,end):在pos位置插入[beg,end]内所有元素副本,无返回值
c.push_back(elem):在尾部添加一个elem
c.pop_back():移除最后一个元素
c.erase(beg,end):移除[beg,end]区间内的所有元素,返回下一个元素的位置
c.resize(num):将元素数量改为num(如果size变大,多出来的新元素都需以默认构造函数构造)
c.resize(num,elem):将元素数量改为num(如果size变大,多出来的新元素都是elem的副本)
vector中访问元素的问题
访问vector中的元素,可以像访问数组一样使用下标形式,即(a[n]),也可以用vector中提供的函数at,即(a.at(n)),但是一般情况下建议使用at,因为at会进行边界检查,如果访问超过了vector的范围,则会抛出异常,但是用数组下标形式不会出现这种检查。只是结果会出现意想不到的值。
#include <vector> #include <iostream> using namespace std; void main() { int a[] = { 1,2,3,4,5 }; int n = sizeof(a) / sizeof(int); vector<int>b(a, a + n); //cout << a[n] << endl; //不会报错,结果意想不到 cout << b.at(n) << endl; //会出现异常 }
vector插入元素
int main(int argc, char* argv[]) { vector<int> v; v.push_back(6); v.push_back(7); v.push_back(8); v.push_back(10); v.insert(v.begin() + 3, 9);//10前插入 v.insert(v.begin(), 5);//首位插入 v.insert(v.end(), 11);//最后插入 vector<int>::iterator i, iend; int j; for (i = v.begin(), j = 0; i != v.end(); i++, j++) cout << "V[" << j << "]" << *i << endl; return 0; }
vector元素删除
#include <vector> #include <iostream> using namespace std; void main(int argc, char* argv[]) { vector<int> v; v.push_back(6); v.push_back(7); v.push_back(8); v.push_back(10); v.insert(v.begin() + 3, 9);//10前插入 v.insert(v.begin(), 5);//首位插入 v.insert(v.end(), 11);//最后插入 v.erase(v.begin());//删除第一个 vector<int>::iterator i; int j; for (i = v.begin(), j = 0; i != v.end(); i++, j++) cout << "V[" << j << "]" << v[j] << endl; v.erase(v.begin(), v.begin() + 2);//删除前2个 for (i = v.begin(), j = 0; i != v.end(); i++, j++) cout << "V[" << j << "]" << v[j] << endl; v.clear();//删除全部元素 }
C++STL 标准模板库
最新推荐文章于 2024-01-14 11:12:52 发布