几种模板
首先认识一下函数模板、类模板、栈模板。
函数模板
函数模板就是一个模型,而模板函数是函数模板经过类型实例化的函数。
如下template<class T>是一个简单的函数模板:
template<class T>
T Max(T a, T b)
{
return a > b ? a : b;
}
int main()
{
cout << Max(2, 5) << endl;//与Max匹配的函数叫模板函数
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);
}
类模板
类模板不是类,需要经过参数实例化之后才是可以用的类(创建对象的时候告诉类模板<类型>)
template<class T>
class A
{
public:
A(int i=0):m_i(i){}
void print() { cout << m_i << endl; }
private:
T m_i
};
int main()
{
//A a;//err
A<int> a(10);//这样经过参数实例化之后才是可以用的类
a.print();
}
使用栈模板
自己模拟栈要很长一段代码:
#define SIZE 10
template<class T>
class SeqStack
{
public:
SeqStack()
{
m_capacity = SIZE;
m_data = new T[m_capacity];
m_top = -1;
}
~SeqStack()
{
delete[]m_data;
m_data = nullptr;
}
void Push(int v)
{
if (IsFull())return;
m_data[++m_top] = v;
}
void Pop()
{
if (IsEmpty())
{
return;
}
m_top--;
}
bool IsEmpty()
{
return m_top == -1;
}
bool IsFull()
{
return m_top >= m_capacity - 1;
}
int GetTop() //要优化
{
if (IsEmpty())
return 0;
return m_data[m_top];
}
private:
T* m_data;
int m_top;
int m_capacity;
};
int main()
{
SeqStack<int> ss;
ss.Push(1);
ss.Push(2);
ss.Push(3);
while (!ss.IsEmpty())
{
cout << ss.GetTop() << " ";
ss.Pop();
}
}
栈模板就可以直接用,带上头文件#include<stack>,很方便,效果跟自己模拟是一样的
int main()
{
stack<int> ss;
ss.push(1);
ss.push(2);
ss.push(3);
while (!ss.empty())
{
cout << ss.top() << endl;
ss.pop();
}
}
STL 标准模板库
STL的重要的组件:容器、算法、迭代器
容器:存放数据
算法:操作数据
迭代器:容器和算法之间的粘合器——通过迭代器把容器里的东西取出,给算法操作(指针)
STL是泛型程序库:所有组件可以针对任意型别运作。
使用
例:从标准输入读取一段整数,将这些整数存放在一个动态开辟的数组中,数组的
第一个元素存储整数的个数,以后依次是这些整数。
void main()
{
vector<int> vv;
copy(istream_iterator<int>(cin), istream_iterator<int>(),
back_insert_iterator<vector<int>>(vv));
copy(vv.begin(), vv.end(), ostream_iterator<int>(cout, " "));
}
容器
•容器:用来管理某类对象的集合。容纳特定数据类型对象的集合,STL容器是将最常用的一些数据结构实现出来.包含了许多数据结构,如:vector,queue,statck…,string也可以看作是一个容器.
•分类:容器用来管理一组元素,为了适应不同需要,STL根据数据在容器中排列的特性,容器可分为序列式容器和关联式容器两种.
•序列式容器:可序群集,其中每个元素都有固定位置——取决于插入时机和地点,与元素的值没有关系,如果你以追加方式对一个群集置入n个元素,它们的排列次序将和置入次序一致。如vector,deque,list
•关联式容器:已序群集,元素位置取决于特定的排序准则,和插入顺序无关。如果你将n个元素置入这样的群集中,它们的位置取决于元素值,和插入次序无关。STL提供了4个这样的容器:set,map,multiset,multimap。
关联式容器也可被视为特殊的序列式容器,因为已序群集正是根据某个排序准则排列而成。
序列式容器
vector容器
向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。
序列式容器。
vector:将其元素置于一个动态数组中加以管理,是一种动态数组,是基本数组的类模板,用于代替数组,支持随机存取。
int main()
{
vector<int> v;
//v里面的构造方法
vector<int> v1(5);//5个0
vector<int> v2(4, 7);//4个7
int arr[5] = { 1,2,3,4,5 };
vector<int> v3(arr,arr+5);//1,2,3,4,5
for (int i = 0; i < v2.size(); i++)
cout << v2[i] << " ";
cout << endl;
v.push_back(1);
v.push_back(2);
v.push_back(40);
v.push_back(3);
for (int i = 0; i < v.size(); i++)
cout << v[i] << " ";
cout << endl;
}
普通二维数组必须定义列数,如a[][3],但vector的每行列数可以不一样
void main()
{
vector<int> v;
vector<vector<int>> vv;//vv相当于一个二维数组
v.push_back(1);//1
vv.push_back(v);//1
v.push_back(2);//1 2
vv.push_back(v);
//1
//1 2
v.push_back(3);//1 2 3
vv.push_back(v);
//1
//1 2
//1 2 3
for (int i = 0; i < vv.size(); i++)
{
for (int j = 0; j < vv[i].size(); j++)
cout << vv[i][j] << " ";
cout << endl;
}
}
vector定义后不能直接赋值,必须有东西存进去再修改
void main()
{
vector<int> v;
//v.resize(5);
v[0] = 5;
//这相当于下面这两行,是不行的
//int a;
//a[0] = 6;
}
deque容器
双端队列容器,它是一个动态数组,支持随机读取,可以向两端发展,头插尾插都快。与vector不同的是,它提供了push_front()成员函数,支持头插
void print(int n)
{
cout << n << " ";
}
int main()
{
deque<int>dd;
dd.push_front(1);//比vector多的
dd.push_back(2);
dd.emplace(dd.begin()+1, 5);//按位置插入
dd.emplace_back(10);
dd.emplace_front(20);
for (int i = 0; i < dd.size(); i++)
{
cout << dd[i] << " ";
}
cout << endl;
swap(*dd.begin(), *(dd.end() - 1));
for_each(dd.begin(), dd.end(), print);
}
![](https://img-blog.csdnimg.cn/img_convert/5ae63b836cc1481d9629482832cbf2de.png)
list容器
带头节点的双向循环链表
#include<list>
void main()
{
list<int> ll;
ll.push_back(1);
ll.push_back(2); //inserttail
ll.push_front(3); //inserthead
ll.push_front(4);
ll.insert(ll.begin(), 10);
//ll.assign(5, 2);
ll.remove(4);
ll.pop_back();
ll.pop_front();
list<int>::iterator iter;
for (iter = ll.begin(); iter != ll.end(); iter++)
{
cout << *iter << " ";//3 1
}
cout << endl;
}
关联式容器
set容器
set集合,去除重复元素
关联式容器,默认从小到大排序
class Node
{
public:
Node():m_next(nullptr){}
Node(int v):m_value(v),m_next(){}
private:
int m_value;
Node* m_next;
};
int main()
{
set<int> ss;
ss.insert(1);
ss.insert(3);
ss.insert(5);
ss.insert(4);
ss.insert(3);
set<int>::iterator iter;
for (iter = ss.begin(); iter != ss.end(); iter++)
{
cout << *iter << " ";
}
}
![](https://img-blog.csdnimg.cn/img_convert/7365821ad7cb468ba8c4d519a98d5b3b.png)
set可以解决寻找有环链表入环结点、两链表合并的结点。
判断是否有环
class Node
{
public:
Node() :m_next(nullptr) {}
Node(int v) :m_value(v), m_next(nullptr) {}
int m_value;
Node* m_next;
};
Node* IsCircle(Node* head)
{
set<Node*> ss;
Node* p = head;
while (p != nullptr)
{
if (ss.find(p) != ss.end())
break;
ss.insert(p);
p = p->m_next;
}
return p;
}
void main()
{
Node a(1), b(2), c(3), d(4), e(5), f(6);
Node* head = &a;
a.m_next = &b;
b.m_next = &c;
c.m_next = &d;
d.m_next = &e;
e.m_next = &f;
f.m_next = &d;
Node* p = nullptr;
if (p = IsCircle(head))
cout << p->m_value << endl;
else
cout << "no " << endl;
}
设定set排序方式
设定set时在<>中加上 类型和设置排序方式的函数
template<class T>
class Less
{
public:
bool operator()(const T& a, const T& b)
{
return a < b;
}
};
class Cmp
{
public:
bool operator()(const int& a, const int& b)const
{
return a > b;
}
};
void main()//
{
set<int, Cmp> ss;
ss.insert(1);
ss.insert(5);
ss.insert(8);
ss.insert(3);
ss.insert(2);
set<int, Cmp>::iterator iter;
for (iter = ss.begin(); iter != ss.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
设定set排序内容
重载小括号使其成为伪函数(类像函数一样使用)
class Student
{
public:
Student(string name, int age) :m_name(name), m_age(age) {}
string m_name;
int m_age;
};
class CmpStudent
{
public:
bool operator()(const Student& a, const Student& b)const
{
return a.m_age < b.m_age;
}
};
void main()
{
set<Student, CmpStudent> ss;
ss.insert(Student("aaa", 1));
ss.insert(Student("ccc", 3));
ss.insert(Student("bbb", 2));
ss.insert(Student("fff", 6));
set<Student>::iterator iter;
for (iter = ss.begin(); iter != ss.end(); iter++)
cout << iter->m_name << " " << iter->m_age << endl;
}
map容器
map映射,里面的元素都是成对出现的。
map中所有元素都是pair,pair中的第一个元素是key,起到了索引的作用;第二个是value(实值),所有的都会根据键值按照一定的准则进行排序。
有size,empty,find,insert,swap,count,erase,clear等使用方法.
map可以直接赋值,也可以用pair赋值。
class Cmp
{
public:
bool operator()(string a, string b)const
{
return a > b;
}
};
void print(map<string, float, Cmp> m)
{
map<string, float>::iterator iter;
for (iter = m.begin(); iter != m.end(); iter++)
cout << iter->first << " " << iter->second << endl;
}
void main()
{
//第一种赋值方式
map<string, float, Cmp> mm;
mm["apple"] = 5.6f;
mm["orange"] = 3.5f;
mm["bananan"] = 3.5f;
cout << mm["apple"] << endl;//5.6f
//第二种方式
pair<string, float> p = { "aaa",4 };
mm.insert(p);
p = { "bbb",6 };
mm.insert(p);
p = make_pair("ccc", 7);
mm.insert(p);
mm.insert(map<string, float, Cmp>::value_type("ddd", 6));
print(mm);
}
![](https://img-blog.csdnimg.cn/img_convert/0f0b07fc9fab4f19a26ae9246c77f13d.png)
class CMP
{
public:
bool operator()(int a, int b)const
{
return a > b;
}
};
void main()
{
map<int, int, CMP> mm;
//第三种方式
mm.insert(pair<int, int>(3, 2));
mm.insert(pair<int, int>(13, 2));
mm.insert(pair<int, int>(33, 2));
mm.insert(pair<int, int>(35, 2));
map<int, int, CMP>::iterator iter;
for (iter = mm.begin(); iter != mm.end(); iter++)
cout << iter->first << " " << iter->second << endl;
}
![](https://img-blog.csdnimg.cn/img_convert/b3934d3fdb37402c891e15455a9b3b08.png)
算法
•算法:用来处理群集内的元素。它们可以出于不同的目的而搜寻,排序,修改,使用那些元素。是一种应用在容器上以各种方法处理其内存的行为或功能,如sort(排序),copy(拷贝)…,算法由模板函数体现,这些函数不是容器类的成员函数,是独立的函数,它们可以用于STL容器,也可以用于普通的C++数组等.
•头文件:#include<algorithm>在STL的泛型算法中有4类基本的算法:
•1)变序型队列算法: 可以改变容器内的数据;
•2)非变序型队列算法:处理容器内的数据而不改变他们;
•3)排序值算法:包涵对容器中的值进行排序和合并的算法,还有二叉搜 索算法 ,
•4)通用数值算法:此种算法不多,涉及到专业领域中有用的算术操作,独立包涵于头文件<numeric>中,在此不多做解释
排序sort()
使用必须加上头文件#include<algorithm>。
sort默认是做非递减排序,用的类模板,这个自己也可以模拟,如下:
自己也可以写个函数传入sort使其做非递增排序。
bool great(int a, int b)
{
return a > b;
}
template<class T>
class Great
{
public:
bool operator()(T a, T b)
{
return a > b;
}
};
void main()
{
int a[] = { 1,3,2,5,4,7,6,9,8,0 };
int n = sizeof(a) / sizeof(a[0]);
//sort(a, a + n,greater<int>());
//sort(a, a + n, great);//函数模板,用函数名当做函数指针传入
sort(a, a + n, Great<int>());//类模板,运用了()的重载
for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;
}
遍历for_each()
for_each()函数是C++ STL中的一个遍历函数,函数原型如下:
for_each(InputIterator first, InputIterator last, Function functor);
拷贝copy()
复制 [first, last) 所定义的范围中的元素到始于 d_first 的另一范围。
函数原型:
template<class InputIterator, class OutputIterator>
inline OutputIterator copy(
InputIterator first,
InputIterator last,
OutputIterator result
);
for_each()和copy()的使用:
void print(int n)
{
cout << n << " ";
}
int s = 0;
void Sum(int n)
{
s = s + n;
}
void main()
{
int a[5] = { 1,2,3,4,5 };
int b[5];
copy(a, a + 5, b);//把[a,a+n)复制到b
// copy(b, b + 5, ostream_iterator<int>(cout, ","));
for_each(b, b + 5, print);//输出12345
for_each(b, b + 5, Sum);//输出15
cout << "s = " << s << endl;
}
反转函数reverse
将区间[iterator1,iterator2)内的元素反转
交换swap_ranges
函数原型:
template<typename T1, typename T2>
void swap(std::pair<T1,T2> left, std::pair<T1,T2> right);
前两个参数分别是第一个序列的开始和结束迭代器,第三个参数是第二个序列的开始迭代器。显然,这两个序列的长度必须相同。这个算法会返回一个迭代器,它指向第二个序列的最后一个被交换元素的下一个位置。
使用:
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 = find(a, a + n, 15);
cout << *(p - 1) << endl;
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);
cout << count(a, a + 5, 2) << endl;
cout << count_if(a, a + 5, Less5<int>()) << endl;
}
![](https://img-blog.csdnimg.cn/img_convert/c4eacd96c0474b0b83550b52688fecdf.png)
判断包含关系includes
函数原型
template <class InputIterator1, class InputIterator2, class Compare>
bool includes ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, Compare comp );
测试 [first1,last1)里面是否包含了[first2,last2)里面的所有元素。
int main(void)
{
int a[10] = { 12,0,5,3,6,8,9,34,32,18 };
int b[5] = { 5,3,6,8,9 };
int d[15];
sort(a, a + 10);
for (int i = 0; i < 10; i++)
cout << " " << a[i];
sort(b, b + 5); // 3 5 6 8 9
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!";
merge(a, a + 10, b, b + 5, d); //合并
for (int j = 0; j < 15; j++)
cout << " " << d[j];
return 0;
}
归并排序merge
merge只有归并部分,使用它必须是两个有序数组经行归并(先用sort()排序)
void main()
{
int a[5] = { 5,4,1,2,3 };
int b[5] = { 6,8,1,4,6 };
int c[10];
sort(a, a + 5);
sort(b, b + 5);
merge(a, a + 5, b, b + 5, c);
}
迭代器
迭代器简称it,它封装了指针(可以把它看成指针用)。它是算法和容器的粘合器——通过迭代器把容器里的东西取出
•迭代器:用来在一个对象群集的元素上进行遍历动作。这个对象群集或许是个容器,或许是容器的一部分。迭代器的主要好处是,为所有容器提供了一组很小的公共接口,利用这个接口,某项操作就可以行进至群集内的下一个元素。每一种容器都提供了自己的迭代器,而这些迭代器了解该种容器的内部结构,所以能够知道如何正确行进。迭代器的接口和一般指针差不多。
•可将其看作是一个指向容器中元素的普通指针,用迭代器来访问容器中的元素,是它将算法和容器连接在一起,每个容器都有自己的迭代器,只有容器自己才知道如何访问自己的元素.
容器的迭代器
•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(elen):在尾部添加一个elem
•c.pop_back():移除最后一个元素(但不回传)
•c.erase(beg,end):移除[beg,end]区间内的所有元素,返回下一个元素的位置
•c.resize(num):将元素数量改为num(如果size变大,多出来的新元素都需以默认构造函数构造)
•c.resize(num,elem):将元素数量改为num(如果size变大,多出来的新元素都是elem的副本)
使用迭代器从键盘输入,排序,输出
istream_iterator输入流迭代器类,不传参:默认为收到非法输入结束
back_insert_iterator向后插入类
vv.begin(),vv.end()容器自带使用的迭代器:
begin()返回指向首元素的迭代器,vv.end()指向尾元素的下一个
ostream_iterator(输出,分隔符);输出迭代器
void Print(int n)
{
cout << n << " ";
}
int main()
{
//创建一个容器vv
vector<int> vv;
//copy输入流迭代器获取cin内容,到非法字符结束,向后插入到vector<int>类型容器vv中
copy(istream_iterator<int>(cin), istream_iterator<int>(),
back_insert_iterator<vector<int>>(vv) );
//排序:从vv首元素,到vv尾元素的下一个
sort(vv.begin(), vv.end());
// 将vv开头到结尾copy到输出流迭代器中,以空格分割
copy(vv.begin(), vv.end(), ostream_iterator<int>(cout, " "));
//输出
cout << endl;
//foreach也可以输出
for_each(vv.begin(), vv.end(), Print);
return 0;
}
![](https://img-blog.csdnimg.cn/img_convert/cf969c8acd4744d7858ad4d91a2a3ff7.png)
用vector做一个确定行列的二维数组
容器push_back操作:字符串向后插入
二维数组:在一个容器里存放另一个容器
int main()
{
vector<vector<int>> vv;//二维数组
int i, j;
//创建3行4列的容器
for (i = 0; i < 3; i++)
{//给每一行添加一个动态构造的vector,一共i行
vv.push_back(vector<int>());//向后插入
for (j = 0; j < 4; j++)
{//每一行放入j个0
vv[i].push_back(0);//把0放进去
}
}
//输出
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
cout << vv[i][j] << " ";
}
cout << endl;
}
}
![](https://img-blog.csdnimg.cn/img_convert/ed58b48847f84146afb406d85290b135.png)
存字符串的数组
字符串就相当于一个二维的存char的数组,存字符串的数组相当于一个“三维数组”。
v.append( 个数,追加的内容 ):容器存储内容的追加
int main()
{
vector<string> v;//装字符串
vector<vector<string>>vv;//装字符串的数组
int i, j;
for (i = 0; i < 3; i++)
{
v.push_back("");//字符串
v[i].append(5,'*');//追加5个*,用于字符
}
for (i = 0; i < 3; i++)
{
cout << v[i] << endl;
}
for (i = 0; i < 4; i++)
{
vv.push_back(vector<string>());//vv里面是字符串数组的数组
for (j = 0; j < 5; j++)
{
vv[i].push_back("11111");//vv[i]里面是字符串数组
cout << vv[i][j] << endl;//vv[i][j]里面是字符串
}
cout << vv[i][4][0] <<"-----"<< endl;//这里面是字符
}
}
用这个可以装n皇后问题的结果。
![](https://img-blog.csdnimg.cn/img_convert/2db2c41d53634865a9b21ea879fb1b8c.png)
用一个迭代器输出
定义vector的一个迭代器(跟指针很像)
基类型::迭代器 名字
v.at(i)相当于v[i],但是at做越界异常处理了,v[i]不会管越界
v.size()取容器大小
int main()
{
int arr[5] = { 1,2,3,4,5 };
vector<int> v1( arr,arr + 5 );
vector<int> v2;
vector<int> v3(v1);
int i;
for (i = 0; i < v1.size(); i++)
{
cout << v1[i] << " "<<v1.at(i)<<endl;
}
v2 = v3;//vector中重载了赋值运算符
//定义vector的一个迭代器
vector<int>::iterator iter;//基类型::迭代器 名字
//迭代器指向v2开头,到末尾,输出
for (iter = v2.begin(); iter != v2.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
![](https://img-blog.csdnimg.cn/img_convert/3b18373ad45d46a19e771df59c36d8ce.png)
区分容器容量,大小
v.reserve();//设置最小容纳数量
v.resize();//设置容器大小,如果缩小容器大小,则容器大小范围外的东西都会被清零。
v.size();//输出容器大小
v.capacity();//输出容量大小
int main()
{
int num = 0;
int* p = nullptr;
vector<int> v;
v.reserve(10);//最小容量为10
vector<int>::iterator iter;
for (int i = 1; i < 20; i++)
{
v.push_back(i);
}
v.resize(5);//将v的大小改变为5
cout << v.size() << endl;//大小5
cout << v.capacity() << endl;//容量10
v.resize(10);//改变大小,resize之后的东西都没有了
for (iter = v.begin(); iter != v.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
![](https://img-blog.csdnimg.cn/img_convert/1227e61e186a431da1f5be14c4bf7fc0.png)
vector赋值操作
v.assign(个数, 内容);//重新给值
v.front();//返回容器头的引用
v.back();//返回容器尾的引用
v1.begin(), v1.end()//返回开始的迭代器,末尾元素下一个的迭代器
v.pop_back();//删除尾部
v.erase( ,);//可以删除某个范围的
int main()
{
int arr[5] = { 1,2,3,4,5 };
vector<int> v(arr,arr+3);//1,2,3,4,5
v.assign(5, 3);//重新给值3,3,3,3,3
vector<int>v1(arr, arr + 5);//1,2,3,4,5
v.assign(v1.begin(), v1.end());//v = v1;可以v.assign(v1.begin(), v1.begin()+3)//1,2,3,4,5
vector<int>v2(arr, arr + 5);
//v.clear();
v.insert(v.begin(),100);//100,1,2,3,4,5
v.insert(v.begin() + 2, arr, arr + 3);//100,1,1,2,3,2,3,4,5
v.insert (v.begin(), v1.begin(), v1.end());//1,2,3,4,5,100,1,1,2,3,2,3,4,5
v.insert(v.end() - 1, 3, 40);//1,2,3,4,5,100,1,1,2,3,2,3,4,40,40,40,5
vector<int>::iterator iters = v.begin();
vector<int>::iterator itere = v.end();
for (; iters != itere; iters++)
{
cout << *iters << " ";
}
cout << endl;
cout << "front:" << v.front() << endl;//1
cout << "back:" << v.back() << endl;//5
//删除
v.pop_back();1,2,3,4,5,100,1,1,2,3,2,3,4,40,40,40
cout << "size:" << v.size() << endl;//16
v.erase(v.begin());//2,3,4,5,100,1,1,2,3,2,3,4,40,40,40
v.erase(v.begin(), v.begin() + 3);//5,100,1,1,2,3,2,3,4,40,40,40
iters = v.begin();
itere = v.end();
for (; iters != itere; iters++)
cout << *iters << " ";
cout << endl;
}
![](https://img-blog.csdnimg.cn/img_convert/a381572c5bff41e09a10ed0f73bd43fc.png)
字符串的迭代器
跟容器的差不多
string查找、比较、插入、移除、子串赋值
int main()
{
string s = "helloworld";
const char* str = s.c_str();
cout << str << endl;
const char* str2 = "hello";
string s2 = str2;
s2 = "world";
cout << s2 << endl;
s2.assign("ssss");//重新赋值
cout << s2 << endl;
s2[3] = 'k';
cout << s2 << endl;
s2.at(2) = 'p';//改某个
cout << s2 << endl;
s2 = s2 + "tttttt";
cout << s2 << endl;
s2.append("kkkk");//追加
cout << s2 << endl;
}
![](https://img-blog.csdnimg.cn/img_convert/e355f360a2d44617ab93f0a8bf571edf.png)
int main()
{
string s = "abcdefgef";
string s1 = "abcf";
string sub = "bd";
string sub2 = "ef";
int pos = s.find(sub);//查找字符串
cout << pos << endl;//找不到返回-1
pos = s.find(sub2);
cout << pos << endl;//找到,返回当前字符串的起始位置,4
pos = s.rfind(sub2);
cout << pos << endl;//从右边找
int ret = s.compare(s1);//比较大小
cout << ret << endl;//s比s1小,返回-1
int ret1 = s1.compare(s);
cout << ret1 << endl;//s1比s大,返回1
//子串
string s2 = s.substr(0, 2);//取子串赋值给s2,从0开始取2个,(偏移量,数量)
cout << s2 << endl;
//插入
s2.insert(0, "kkk");//在0号下标插入kkk
cout << s2 << endl;
//移除
s2.erase(0, 5);//从0开始移除5个
cout << s2 << endl;
}
![](https://img-blog.csdnimg.cn/img_convert/cdbd4371d61c4201a4c69e8d8dd91994.png)