顺序容器部分习题(基础)

来源:互联网 发布:淘宝造物节2017图片 编辑:程序博客网 时间:2024/05/16 23:45

9.4: 编写一个函数,接受一个对指向vector的迭代器,和一个int值.在两个迭代器指定的范围查找给定的值,返回一个bool值来指出是否找到

#include <iostream>#include <vector>#include <iterator>using namespace std;// 注意迭代器的类型 和迭代器的写法iteratorbool 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 arraydequeback不适用于forward_listc.back()  返回c的尾元素的引用 c不能为空c.front() 返回c的首元素的引用 c不能为空c[n] 返回c中下标为n的元素的引用 n是无符号整数 若n>=c.size() 则错误c.at(n) 返回下标为n的元素的引用 下标不能越界警告: 若空容器调用front或back则就像下标越界 错误删除元素这些操作操作会改变array的大小所以不适用于arrayforward_list 有特殊的eraseforward_list 不支持pop_back; vectorstring不支持pop_front;c.pop_back() 删除c的尾元素,若c为空 则函数未定义。 函数返回voidc.pop_front() 删除c的首元素, c不为空 函数返回voidc.erase(p) 删除迭代器p所指向的元素,返回p之后的元素的迭代器,p不能为尾后迭代器c.erase(b, e) 删除b 和e 迭代器所指范围内的元素包括本身,返回e之后的迭代器c.clear() 删除c中所有的元素警告:删除deque中首尾之外的任何元素,都会使迭代器,引用,指针失效。指向vectorstring中删除点之后位置的迭代器,引用,指针都会失效;再删除元素之前必须确保他们存在改变容器的大小c.resize(n)  调整c的大小为n 如果n < c.size() 多出的会被删除 若必须添加,就要对他初始化;c.resize(n, t) 调整大小为n 初始化为t  顺序容器会不会失效总结对vectorstring删除或增加,删除或增加 后面的迭代器,指针或引用对失效,前面的不会对deque除了首尾之外的任何位置进行修改都会使指针,迭代器,引用失效。如果是对首尾修改,只有迭代器会失效其他不会对list 和forward_list 不论修改哪,迭代器,指针,引用都不会失效管理迭代器建议,对于vectorstringdeque 最好每次都重新确定其迭代器是否正确最好使用 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;}