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

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 arraydeque
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; vectorstring不支持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中首尾之外的任何元素,都会使迭代器,引用,指针失效。指向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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值