9.4: 编写一个函数,接受一个对指向vector的迭代器,和一个int值.在两个迭代器指定的范围查找给定的值,返回一个bool值来指出是否找到
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
// 注意迭代器的类型 和迭代器的写法iterator
bool search(vector<int>::iterator beg, vector<int>::iterator ed, int i)
{
while (beg != ed)
{
if (*beg == i)
return true;
++beg;
}
return false;
}
int main()
{
vector<int> vec{1, 2, 3, 4, 5};
int i;
cout << "输入想要找的值" << endl;
cin >> i;
int fag = search(vec.begin(), vec.end(), i);
if (fag)
cout << "找到" << endl;
else
cout << "未找到" << endl;
return 0;
}
9.5重写上一题,返回一个迭代器指向找到的元素:
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
vector<int>::const_iterator find(vector<int>::const_iterator begin,
vector<int>::const_iterator end, int i)
{ // 此时*begin不可以被修改
while (begin != end)
{
if (*begin == i)
return begin; // 找到返回该元素迭代器
++begin;
}
return end; // 未找到返回最后一个迭代器
}
int main()
{
vector<int> vec{1, 3, 4, 5, 6 };
cout << "请输入要查找的值" << endl;
int i;
cin >> i;
auto a = find(vec.cbegin(), vec.cend(), i);
if (a != vec.cend())
cout << "找到" << endl;
else
cout << "未找到" << endl;
return 0;
}
20:编写程序从一个list拷贝元素到两个deque中,值为偶数的所有元素都拷贝到一个deque中,而奇数都拷贝到另一个deque中
#include <iostream>
#include <list>
#include <deque>
using namespace std;
int main()
{
list<int>list1{1, 2, 3, 4, 5};
deque<int>deque_d;
deque<int>deque_f;
auto i = list1.begin();
while (i != list1.end())
{
if (*i % 2 == 0)
{
deque_d.push_back(*i);
++i;
}
else
{
deque_f.push_back(*i);
++i;
}
}
cout << "list1 的元素是: ";
for (auto &i : list1)
cout << i << " ";
cout <<"\n偶数为: ";
for (auto i = deque_d.begin(); i != deque_d.end(); ++i)
{
cout << *i << " ";
}
cout << "\n奇数是: ";
for (auto &i : deque_f)
{
cout << i << " ";
}
return 0;
}
//list1 的元素是: 1 2 3 4 5
//偶数为: 2 4
//奇数是: 1 3 5
24:编写程序,分别使用at,下标运算符,front,和begin提取一个vector中的一个元素,在空vector中测试:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
// 访问元素
// vector<int>vec = {1, 2, 3};
// cout << vec.front() << " " << vec.back() << " " << vec.at(1) << " "
// << vec[1] ;
list<int> list1 = {1, 2, 3};
auto i = list1.begin();
auto e = list1.end();
// 范围性删除
// i = list1.erase(++i, ++list1.begin()); // 当删除迭代器范围相等时
// 相当于删除一个元素
list1.erase(i, --e);
auto it = list1.begin();
while (it != list1.end())
{
cout << *it++ << " ";
}
return 0;
}
26:使用下面代码定义的ia,将ia拷贝到一个vector和一个list中,使用单迭代器版本的erase从list中删除奇数元素,从vector中删除偶数元素
int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
#include <iostream>
#include <list>
#include <vector>
using namespace std;
//删除操作 拷贝操作
int main()
{
int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
vector<int>vec (ia, ia+11); // 拷贝数组内容
list<int>list1(vec.begin(), vec.end()); // 拷贝容器内容
auto it = vec.begin();
while (it != vec.end()) // 去除偶数部分
{
if (*it % 2 == 0)
{
it = vec.erase(it);
}
else
++it;
}
auto i = vec.begin();
cout << " 奇数 :" << endl;
while (i != vec.end())
{
cout << *i++ << " ";
}
cout << endl;
cout << " 偶数 :" << endl;
// 去除奇数部分
for (auto it = list1.begin(); it != list1.end(); )
{
if (*it % 2 != 0)
it = list1.erase(it);
else
++it;
}
for (auto &it : list1)
cout << it << " ";
cout << endl;
return 0;
}
32
编写改变容器的循环程序
// 很好的题 删除偶数部分 复制奇数部分
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
vector<int>vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto it = vec.begin();
while (it != vec.end())
{
if (*it % 2 == 0)
{
it = vec.erase(it); // 删除偶数
}
else if (*it % 2 != 0)
{
//关键是要看看这一句
it = vec.insert(it, *it); // *it++ 是错误的
it += 2; // 需要跳过本身和复制的一个数
// 如果是list类型容器就不能用it+=2需要分开
//it++;
//it++;
}
}
cout << "结果为:\n";
for (auto &it : vec)
{
cout << it++ << " ";
}
return 0;
}
33:探讨insert
使用后迭代器是否失效
#include <iostream>
#include <vector>
using namespace std;
//特别注意
int main()
{
vector<int> vec = {1, 2, 3, 4, 5};
auto begin = vec.begin();
while (begin != vec.end())
{
++begin;
begin = vec.insert(begin, 42); // insert 是插入begin之前返回42的迭代器
// vec.insert(begin, 43); // 这是错的 迭代器会失效
++begin;
}
for (auto &it : vec)
{
cout << it << " ";
}
return 0;
}
//结果:
//1 42 2 42 3 42 4 42 5 42
//vector是如何增长的课本318:
35: 解释一个vector的capacity和size的区别:
vector 的 capacity 表示在不分配新内存的条件下能存放多少元素 而size() 表示已经存放了多少元素
37:为什么list或array没有capacity函数:
list 的标准库是双链表 不需要分配,每次需要时再申请 array是有固定大小的
38:探究vector如何增长:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec;
cout << "vec:size: " << vec.size()<< endl;
cout << "capacity: " << vec.capacity()<<endl;
cout << endl;
// 加入24个元素
for (vector<int>::size_type ix = 0; ix != 24; ix++)
vec.push_back(ix);
// 此时size 应该为 24 , capacity 应该大于或等于24
cout << "vec:size: " << vec.size()<< endl;
cout << "capacity: " << vec.capacity()<<endl;
cout << endl;
vec.reserve(50); // 将capacity设为至少为50甚至更大
// 此时size 应该为 24 , capacity 应该大于或等于50
cout << "vec:size: " << vec.size()<< endl;
cout << "capacity: " << vec.capacity()<<endl;
cout << endl;
//接下来用光预留的空间
while (vec.size() != vec.capacity())
{
vec.push_back(0);
}
// 此时size 应该为 50 , capacity 应该也是50
cout << "vec:size: " << vec.size()<< endl;
cout << "capacity: " << vec.capacity()<<endl;
cout << endl;
vec.push_back(100); // 在向其中加一个元素
// 此时size 应该为 51 , capacity 应该大于51
cout << "vec:size: " << vec.size()<< endl;
cout << "capacity: " << vec.capacity()<<endl;
cout << endl;
return 0;
}
swap使用:
#include <iostream>
#include <list>
#include <vector>
using namespace std;
int main()
{
vector<int> vec = {1, 2, 3, 4};
vector<int> vec1 = {4, 3, 2,1};
cout << "交换前 vec为: ";
for (auto i : vec)
{
cout << i;
}
cout << endl;
auto it = vec.begin();
cout << "交换前v的it指向的是 "<<*it <<endl;
auto it1 = vec1.begin();
cout << "交换前v1的it1迭代器指向的是 :"<<*it1 << endl;
vec1.swap(vec); // 交换两个容器
cout << "交换后vec 为";
for (auto i : vec)
{
cout << i ;
}
cout << endl;
cout << "交换后v原来的it现在指向" << *it <<endl;
cout << "交换后v1原来的it1现在指向" << *it <<endl;
return 0;
}
/*
若交换前定义一个it 指向元素值为1 的迭代器,交换后it还是指向1,改变的只是容器内部的数据结构
交换后迭代器不变 ,引用, 指针都不变
*/
vector初始化
#include <iostream>
#include <vector>
#include <string>
int main()
{
vector<int> v1(10); // v1里面有10个元素 都是0
vector<int> v2{10}; // v2里面有一个元素 10;
vector<int> v3(10, 1); // v3里面有10个元素都是1
vector<int> v4{10, 1}; // v4里面有连个元素10,1;
// string容器初始化
vector<string> v5{"hi"}; // 列表初始化 v5有一个元素
//注意
vector<string> v6("hi"); //错误,不能使用字面值构建vector对象
vector<string> v7{10}; // v7有10个默认初始化的元素
vector<string> v8{10, "hi"} // v8有10个"hi"元素
vector<string> v9(10, "hi") // 和v8一样
int a[5] = {1, 2, 3, 4, 5}; // 字符容器也是如此
vector<int>v1 (begin(a), end(a));
vector<int> v2(a, a+5);
return 0;
}
//访问容器知识点:
//包括array在内的每一个顺序容器都有一个front成员函数,除了forward_list之外的所有容器都有一个back成员函数,
在解引用前先检查是否有元素
if (c.empty())
{
auto val = *c.begin();
auto val2 = *c.front(); // val val2 都是c容器的第一个元素
auto last = c.end();
auto val3 = *(--last); // c容器的最后一个元素 或者--end()
auto val4 = c.back(); // 不支持forward_list 其他都行
}
在顺序容器中访问元素的操作:
at和下标操作只适用于string vector array 和 deque
back不适用于forward_list
c.back() 返回c的尾元素的引用 c不能为空
c.front() 返回c的首元素的引用 c不能为空
c[n] 返回c中下标为n的元素的引用 n是无符号整数 若n>=c.size() 则错误
c.at(n) 返回下标为n的元素的引用 下标不能越界
警告: 若空容器调用front或back则就像下标越界 错误
删除元素
这些操作操作会改变array的大小所以不适用于array
forward_list 有特殊的erase
forward_list 不支持pop_back; vector和string不支持pop_front;
c.pop_back() 删除c的尾元素,若c为空 则函数未定义。 函数返回void
c.pop_front() 删除c的首元素, c不为空 函数返回void
c.erase(p) 删除迭代器p所指向的元素,返回p之后的元素的迭代器,p不能为尾后迭代器
c.erase(b, e) 删除b 和e 迭代器所指范围内的元素包括本身,返回e之后的迭代器
c.clear() 删除c中所有的元素
警告:
删除deque中首尾之外的任何元素,都会使迭代器,引用,指针失效。指向vector和string中删除点之后位置的迭代器,引用,指针都会失效;
再删除元素之前必须确保他们存在
改变容器的大小
c.resize(n) 调整c的大小为n 如果n < c.size() 多出的会被删除 若必须添加,就要对他初始化;
c.resize(n, t) 调整大小为n 初始化为t
顺序容器会不会失效总结
对vector和string删除或增加,删除或增加 后面的迭代器,指针或引用对失效,前面的不会
对deque除了首尾之外的任何位置进行修改都会使指针,迭代器,引用失效。如果是对首尾修改,只有迭代器会失效其他不会
对list 和forward_list 不论修改哪,迭代器,指针,引用都不会失效
管理迭代器建议,对于vector,string,deque 最好每次都重新确定其迭代器是否正确
最好使用 it = vi.insert(iter, a);
// 赋值:
#include <iostream>
#include <list>
#include <vector>
using namespace std;
// 使用assign 只需要元素类型可以转换就好了
int main()
{
list <const char *> list1={"hello", "world"};
vector<string> vec(list1.cbegin(), list1.cend()); // 两种方法
// vec.assign(list1.cbegin(), list1.cend());
for (const auto &i : vec)
{
cout << i << endl;
}
return 0;
}
拷贝初始化:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
list<double>list1 = {1.1, 2.4, 3, 4};
vector<int> vec (list1.begin(), list1.end());
auto it = vec.begin();
auto it1 = list1.begin();
cout<< "拷贝前: " ;
while(it1 != list1.end()) // 原来的
{
cout << *it1 << " ";
++it1;
}
cout << endl;
cout << "拷贝后: ";
while (it != vec.end()) // 拷贝过来的
{
cout << * it << " ";
++it;
}
cout << endl;
return 0;
}