C++ STL 简单学习
这几天学习stl ,简单记录自己的感悟
STL
容器container
算法 Algorithms
迭代器 iterator
容器适配器 container adaptor
函数对象 functor
容器(container):容器是数据在内存中组织的方法,例如,数组、堆栈、队列、链表或二叉树(不过这些都不是STL标准容器)。STL中的容器是一种存储T(Template)类型值的有限集合的数据结构,容器的内部实现一般是类。这些值可以是对象本身,如果数据类型T代表的是Class的话。
算法(algorithm):算法是应用在容器上以各种方法处理其内容的行为或功能。例如,有对容器内容排序、复制、检索和合并的算法。在STL中,算法是由模板函数表现的。这些函数不是容器类的成员函数。相反,它们是独立的函数。令人吃惊的特点之一就是其算法如此通用。不仅可以将其用于STL容器,而且可以用于普通的C++数组或任何其他应用程序指定的容器。
迭代器(iterator):一旦选定一种容器类型和数据行为(算法),那么剩下唯一要他做的就是用迭代器使其相互作用。可以把达代器看作一个指向容器中元素的普通指针。可以如递增一个指针那样递增迭代器,使其依次指向容器中每一个后继的元素。迭代器是STL的一个关键部分,因为它将算法和容器连在一起。
容器
队列容器:list vector deque
关联容器:set multisets map multimaps
vector 向量
默认构造函数 vectorv1 构造一个初始长度为0的空向量
带单个整形参数的构造函数 vectorv2(n,0) 参数描述向量的初始大小
复制构造函数 vectorv3(v2) 构造一个新的向量 作为已存在的向量的完全复制
带两个常量参数的构造函数 vectorv4(first,last) 产生初始值的为一个区间的向量
算法:
STL算法的大部分都不作为某些特定的容器类的成员函数
变序型队列算法 可以改变容器内的数据
非变序型队列算法 处理容器内的数据不改变它们
排序值算法 对容器的值进行排序和合并的算法 二叉搜索算法 通用数值算法
边序型队列算法 copy swap replace clear remove reverse
迭代器 #include
泛化指针
输入迭代器
输入迭代器
前向迭代器
双向迭代器
随机访问迭代器
流迭代器 可以直接输出 输入流中的值
适配器是用来修改其他组件接口的STL组件,是带有一个参数的类模板(这个参数是操作的值的数据类型)。STL定义了3种形式的适配器:容器适配器,迭代器适配器,函数适配器。
容器适配器 栈 队列 priority_queue
#include <cstring>
#include <vector>
#include <iostream>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <string>
#include <iterator>
#include <algorithm>
#include <fstream>
#include <functional> //其他函数对象 仿函数
#include <windows.h>
using namespace std;
//int ar[10] = {1,2,3,4,5,6,7,8,9,10};
//char * str = "hello world";
//int main()
//{
// vector<int>vec1(ar,ar+10);
// vector<char>vec2(str,str+strlen(str));
// cout<<"vec1:"<<endl;
// for(vector<int>::const_iterator p = vec1.begin();p!=vec1.end();++p)
// cout<<*p;
// cout<<"\n"<<"vec2:"<<endl;
// for(vector<char>::const_iterator p1 = vec2.begin();p1!=vec2.end();++p1)
// cout<<*p1;
// cout<<"\n";
// system("pause");
// return 0;
//}
//迭代器的使用const_iterator
typedef vector<int>INTVECTOR;//自定义类型INTVECTOR
typedef deque<int>INTDEQUE;//自定义类型INTVECTOR
//////////////
//////////////
struct int_max
{
int operator()(int x,int y){return x>y?x:y;}
};//operator()重载“()” (int x,int y)是参数列表
struct adder:public unary_function<double,void>
{//unary_function是一个空基类,不包涵任何操作或变量。只是一种格式说明,它有两个参数,第一个参数是函数对象的使用数据类型,
adder():sum(0){}
double sum;
void operator()(double x){sum += x;}
};
//测试vector容器的功能
//int main()
//{
// INTVECTOR vec1; //对象初始值为空
// INTVECTOR vec2(10,6); //表示10 个值为6的元素
// INTVECTOR vec3(vec2.begin(),vec2.begin()+3); // 初始有3个6 的元素 拷贝构造
// INTVECTOR::const_iterator i; //声明一个名为i的双向迭代器
// cout<<"vec1.begin()-->vec1.end():"<<endl;
// for(i=vec1.begin();i!=vec1.end();++i)
// cout<<*i<<endl; //从前往后显示vec1中的数据
// cout<<"vec2.begin()-->vec2.end():"<<endl;
// for(i=vec2.begin();i!=vec2.end();++i)
// cout<<*i<<endl; //从前往后显示vec2中的数据
// cout<<"vec3.begin()-->vec3.end():"<<endl;
// for(i=vec3.begin();i!=vec3.end();++i)
// cout<<*i<<endl; //从前往后显示vec2中的数据
//
// vec1.push_back(2); //从后面添加一个成员
// vec1.push_back(4);
// vec1.insert(vec1.begin()+1,5);// 在vec1第一个的位置上掺入成员5
// vec1.insert(vec1.begin()+1,vec3.begin(),vec3.end());// 在vec1第一个的位置上vec3 所有成员
// cout<<"after push() and inset() now the vec1 is:"<<endl;
// for(i=vec1.begin();i!=vec1.end();++i)
// cout<<*i<<endl; //从前往后显示vec1中的数据 2 6 6 6 5 4
// vec2.assign(8,1);//从新给vec2赋值,8个成员的初始值都为1
// for(i=vec2.begin();i!=vec2.end();++i)
// cout<<*i<<endl; //从前往后显示vec1中的数据
// cout<<"vec1.front()="<<vec1.front()<<endl;//2
// cout<<"vec1.back()="<<vec1.back()<<endl;//4
// cout<<"vec1.at()="<<vec1.at(5)<<endl;//4
// cout<<"vec1[4]="<<vec1[4]<<endl;
// vec1.pop_back();//移除最后一个成员
// vec1.erase(vec1.begin()+1,vec1.end()-2);//删除成员
// for(i=vec1.begin();i!=vec1.end();++i)
// cout<<*i<<endl; //从前往后显示vec1中的数据
// cout<<"vec1.size()="<<vec1.size()<<endl; //显示序列的状态信息
// cout<<"vec1.empty()="<<vec1.empty()<<endl;
//
// system("pause");
// return 0;
//}
void put_deque(INTDEQUE deque,char* name)
{
INTDEQUE::iterator pdeque;//使用迭代器输出
cout<<"The content of "<<name<<endl;
for(pdeque = deque.begin();pdeque!=deque.end();pdeque++)
cout<<"*pdeque"<<endl; //注意有**号 没有**号的话会报错
cout<<endl;
}
void Printlt(list<int>n)
{
for(list<int>::iterator iter = n.begin();iter!=n.end();++iter)
cout<<*iter<<"";//使用迭代器进行输出循环
}
int main()
{
//INTDEQUE deq1; // 初始化为空
//INTDEQUE deq2(10,6);
//INTDEQUE::iterator i;
//put_deque(deq2,"deq2");
//put_deque(deq1,"deq1");
//deq1.push_back(1);
//deq1.push_back(3);
//cout<<"deq1.push_back() and deq1.push_front(7)"<<endl;
//put_deque(deq1,"deq1");
/*list<int>listn1,listn2;
listn1.push_back(123);
listn2.push_back(0);
listn1.push_back(34);
listn2.push_back(44);
listn1.sort();
listn2.sort();
Printlt(listn1);
cout<<endl;
Printlt(listn2);
cout<<endl;
listn1.merge(listn2);
Printlt(listn1);*/
///////////////////////////元素的值是唯一的
set<int>set1;
for(int i = 0;i < 10;i++)
set1.insert(i);
for(set<int>::iterator p = set1.begin();p!=set1.end();++p)
cout<<*p<<"";
if(set1.insert(3).second) //把3插入set1中 集合已经有3s所以失败
//成功 返回1 错误 返回0
cout<<"set insert success";
else
cout<<"set inset failed";
int a[] = {1,3,3,5,5,6,2,2,31,0};
multiset<int>A;//:set支持唯一键值,set中的值都是特定的,而且只出现一次;而multiset中可以出现副本键,同一值可以出现多次。
A.insert(set1.begin(),set1.end());
A.insert(a,a+10);
cout<<endl;
for(multiset<int>::iterator p = A.begin();p!=A.end();++p)
cout<<*p<<"";
////////////////////////////////////////////////map multimap
// 映射 多重映射
cout<<endl;
map<char,int,less<char>>map1;
map<char,int,less<char>>::iterator maplter;
// char 是键的类型 int是值的类型
map1['c'] = 2;
map1['d'] = 3;
map1['a'] = 1;
map1['b'] = 4;
for(maplter = map1.begin();maplter!=map1.end();++maplter)
cout<<(*maplter).first<<":"<<(*maplter).second;
//first 对应定义中的char值 second 对应定义中的int 值
//检索对应于d键的值should do this
cout<<endl;
map<char,int,less<char>>::const_iterator ptr;
ptr = map1.find('d');
cout<<(*ptr).first<<":"<<(*ptr).second<<endl;
//////////////////////////
//多值比较
multimap<string,string,less<string>>mulmap;
multimap<string,string,less<string>>::iterator p;
//初始化多重映射 multimap
typedef multimap<string,string,less<string>>::value_type vt;
typedef string s;
mulmap.insert(vt(s("Tom"),s("is a student")));
mulmap.insert(vt(s("Tom"),s("is a boy")));
mulmap.insert(vt(s("Tom"),s("is a bad boy of blue")));
mulmap.insert(vt(s("Jerry"),s("is a student")));
mulmap.insert(vt(s("Jerry"),s("is a beautiful girl")));
mulmap.insert(vt(s("DJ"),s("is a student")));
//输出初始化以后的多重映射mulmap
for(p = mulmap.begin();p!=mulmap.end();++p)
cout<<(*p).first<<";"<<(*p).second<<endl;
cout<<"find jerrt"<<endl;
p = mulmap.find(s("Jerry"));
while((*p).first == "Jerry")
{
cout<<(*p).first<<(*p).second<<endl;
++p;
}
/////////////////////////
//输出迭代器ostream_iterator
int arr[6] = {1,2,3,4,12,90};
int arr1[7];
int arr2[6] = {2,3,4,56,5,4};
copy(arr,(arr+6),arr1);
cout<<"arr[6] copy to arr1[7],now arr1:"<<endl;
for(int i = 0;i<7;i++)
cout<<arr1[i];
reverse(arr,arr+6);
//将排序好的arr翻转
cout<<'/n'<<"arr reversed,now arr:"<<endl;
copy(arr,arr+6,ostream_iterator<int>(cout,""));
//将arr赋值到迭代器
swap_ranges(arr,arr+6,arr2);//两个相等大小区间中的值
cout<<'/n'<<"arr2:"<<endl;
copy(arr2,arr2+6,ostream_iterator<int>(cout,""));
////////////////////////////////////////////////
int a1[10] = {12,0,4,3,23,6,48,40,32.90};
int b[5] = {5,3,8,99,9};
int d[15];
sort(a1,a1+10);
for(int i = 0;i<10;i++)
cout<<a1[i];
sort(b,b+5);
if(includes(a1,a1+10,b,b+5))
cout<<'\n'<<"asd"<<endl;
else
cout<<"sorted a dos't contain sorted b";
merge(a1,a1+10,b,b+5,d);
for(int j = 0;j<15;j++)
cout<<" "<<d[j];
/////////////////////////////////////////////
// 字符流的操作 istream_iterator,输出迭代器ostream_iterato
vector<string> v1;
ifstream file("Text1.txt");
if(file.fail())
{
cout<<"open file text failed"<<endl;
//return 1;
}
copy(istream_iterator<string>(file),istream_iterator<string>(),inserter(v1,v1.begin()));//inserter(container,pos) 一个输入迭代器的一个函数 迭代器适配器
copy(v1.begin(),v1.end(),ostream_iterator<string>(cout," "));
cout<<endl;
//////////////////////
double aa[5] = {0.5611,1,1,4,9.9};
vector<double>V(aa,aa+5);
adder result = for_each(V.begin(),V.end(),adder());
cout<<"the sum is "<<result.sum<<endl;
system("pause");
///////////////
return 0;
}
继续学习中。。。