C++ Primer 答案 第九章

本文详细探讨了C++标准库中的各种容器,如list、deque、vector等的使用场景及特性,通过具体代码示例展示了如何高效地进行元素的插入、删除及查找操作,特别关注了迭代器的有效运用及潜在陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9.1
(a) list , 因为需要中间插入
(b) deque , 因为需要在头尾进行插入与删除操作
(c) vector , 因为只需要从尾部插入,再排序即可

9.2
list<deque<int>> l1;

9.3
1.指向同一个容器
2.begin <= end

9.4

bool findInt(vector<int>::iterator begin, vector<int>::iterator &end, int &value)
{
    while(begin != end)
    {
        if(*begin == value)
            return true;
        begin++;
    }
    return false;
}

9.5

vector<int>::iterator findInt(vector<int>::iterator begin, vector<int>::iterator &end, int &value)
{
    while(begin != end)
    {
        if(*begin == value)
            return begin;
        begin++;
    }
    return end;
}

9.6
while(iter1 != iter2)

9.7
vector<int>::size_type 

9.8
读取:list<string>::const_iterator
写入:list<string>::iterator

9.9
cbegin 指定的对象只读

9.10
it1: vector<int>::iterator
it2: vector<int>::const_iterator
it3: vector<int>::const_iterator
it4: vector<int>::const_iterator

9.11
vector<int> vec;    // {}
vector<int> vec(10);    // {10}
vector<int> vec(10,1);  // {1,1,1,1,1,1,1,1,1,1}
vector<int> vec{1,2,3,4,5}; // {1,2,3,4,5}
vector<int> vec(other_vec); // same as other_vec
vector<int> vec(other_vec.cbegin(), other_vec.cend()); // same as other_vec

9.12
第一种类型需要一致,而且是全部拷贝
第二种类型不需要一致,可以选择拷贝范围

9.13
vector<double> vec(listInt.cbegin(), listInt.cend());
vector<double> vec(vecInt.cbegin(), vecInt.cend());

9.14
vector<string> vecString;
vecString.assign(list.cbegin(), list.cend());

9.16
因为它们类型不同,所以先把list初始化成vector后再比较
vector<int> vec1(list.cbegin(), list.cend()) == vector<int> vec

9.17
都是顺序容器,且定义了比较操作

9.18

#include <iostream>
#include <deque>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
    string s;
    deque<string> deque1;
    while(cin>>s)
    {
        if(s == "break")
            break;  //我实在不知道怎么退出了,command+d没用
        deque1.push_back(s);
    }
    for(auto &value :deque1)
        cout<< value << endl;
    return 0;
}

9.19
感觉没啥区别

#include <iostream>
#include <string>
#include <list>
using namespace std;

int main(int argc, char *argv[])
{
    string s;
    list<string> list1;
    while(cin>>s)
    {
        if(s == "break")
            break;  //我实在不知道怎么退出了,command+d没用
        list1.push_back(s);
    }
    for(auto &value :list1)
        cout<< value << endl;
    return 0;
}

9.20

#include <iostream>
#include <deque>
#include <string>
#include <list>
using namespace std;

int main(int argc, char *argv[])
{
    list<int> list1 ={12,3,4,5,32,6,3,33,11};
    deque<int> deque1, deque2;//deque1存偶数,deque2存奇数
    for(auto &value :list1)
    {
        if(value%2 == 0)
            deque1.push_back(value);
        else
            deque2.push_back(value);
    }
    for(auto &value : deque1)
        cout << value << " ";
    cout << endl;
    for(auto &value : deque2)
        cout << value << " ";
    cout << endl;
    return 0;
}

9.21
一样效果,记住insert()的返回值 恰好是指向新元素的迭代器

9.22

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
    vector<int> iv ={12,5,3,5,32,5,5,3,5,11,44,4,22};
    int some_value =5;
    auto cursor = iv.size() / 2;
    auto iter = iv.begin(), mid = iv.begin() + cursor;
    while (iter != mid)
    {
        if(*iter == some_value)
        {
            iter = iv.insert(iter, 2 * some_value); //必须更新iter,因为iter已经失效
            iter++; //iter指向新元素,所以要++
            mid = iv.begin() + ++cursor;
        }
        iter++;
    }
    for(auto &value :iv)
        cout << value << " ";
    cout << endl;
    return 0;
}

9.23
4个值都等于第一个元素的值

9.24
vector<int> v;
cout << v.at(0) << endl; //libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: vector
cout << v[0] << endl;
cout << v.front() <<endl;
cout << *v.begin()<< endl;

9.25
如果elme1 与 elme2 相等,不删除东西
如果elme2 是尾后迭代器,则删除elme1到结尾的元素
如果都是尾后迭代器,不删除东西

9.26

#include <iostream>
#include <vector>
#include <list>
using namespace std;

int main(int argc, char *argv[])
{
    int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
    vector<int> vec(ia, end(ia));
    list<int> lst(ia, end(ia));
    auto vecIt = vec.begin();
    while (vecIt != vec.end())
    {
        if(*vecIt %2 == 0)
            vecIt = vec.erase(vecIt);
        else
            vecIt++;
    }
    auto lstIt = lst.begin();
    while (lstIt != lst.end())
    {
        if(*lstIt %2 != 0)
            lstIt = lst.erase(lstIt);
        else
            lstIt++;
    }
    for(auto i : vec)
        cout << i << " ";
    cout << endl;
    for(auto i : lst)
        cout << i << " ";
    cout << endl;
    return 0;
}

9.28

#include <iostream>
#include <string>
#include <forward_list>
using namespace std;

void insert(forward_list<string> &lst, const string &a, const string &b)
{
    auto prev = lst.before_begin();
    auto it = lst.begin();
    while(it != lst.end())
    {
        if(*it == a)
        {
            lst.insert_after(it, b);
            return;
        }
        else
            prev = it++;
    }
    lst.insert_after(prev, b); //prev的作用体现在,插入只能在尾迭器前一个
}

int main(int argc, char *argv[])
{
    forward_list<string> lst = {"cat", "dog", "apple", "pig"};
    string a = "apple";
    string b = "bird";
    insert(lst, a, b);
    for(auto &i : lst)
        cout << i << " ";
    cout << endl;
    return 0;
}

9.29
(1)添加75个值为0的元素
(2)删除后面90个元素9.31
list: iter += 2; 改为 advance(iter, 2);
fordward_list:

#include <iostream>
#include <forward_list>
using namespace std;

int main(int argc, char *argv[]) {
    forward_list<int> lst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    auto iter = lst.begin();
    auto prev = lst.before_begin();
    while(iter != lst.end())
    {
        if(*iter %2) //复制奇数
        {
            iter = lst.insert_after(iter, *iter);
            prev = iter++;
        }
        else   //删除偶数
            iter = lst.erase_after(prev);
    }
    for(auto i : lst)
        cout << i << " ";
    cout << endl;
    return 0;
}

9.32
不合法,因为执行插入操作后,iter已经失效,iter++未知

9.33
执行插入操作后,begin失效

9.34
无限循环,把++iter 改为 advance(iter, 2);

9.35
size 是存储的元素的个数
capacity 是分配的存储空间个数

9.36
不能

9.37
list 是链表,数据不是连续存储的
array 是固定大小的

9.38
vector<int> vec(10,1);
cout << vec.size() <<endl;
cout << vec.capacity() <<endl;
vec.push_back(1);
cout << vec.size() <<endl;
cout << vec.capacity() <<endl;

输出:
10
10
11
20
可以发现capacity *2 了

9.40
数太多了没试,反正读入1000与1048个词时capacity会增加

9.41
string s(vec.begin(), vec.end());

9.43
//迭代器实现

void replace(string &s, const string &oldVal, const string &newVal)
{
    auto it = s.begin();
    while(distance(it, s.end()) >= distance(oldVal.begin(), oldVal.end()))
    {
        if(string(it, it + oldVal.size()) == oldVal)
        {
            it = s.erase(it, it + oldVal.size());
            it = s.insert(it, newVal.begin(), newVal.end());
            advance(it, newVal.size());
        }
        it++;
    }
}

9.44
//下标实现

void replace(string &s, const string &oldVal, const string &newVal)
{
    string::size_type i =0;
    while(( s.size() - i) >= oldVal.size())
    {
        if(s.substr(i, oldVal.size()) == oldVal)
        {
            s.replace(i,oldVal.size(), newVal);
            i = i + newVal.size();
        }
        else
            i++;
    }
}

9.45

string fun(string name, const string &s1, const string &s2)
{
    name.insert(name.begin(), s1.begin(),s1.end()); //3个参量都应该是迭代器
    name.append(s2);
    return name;
}

9.46

string fun(string name, const string &s1, const string &s2)
{
    name.insert(0, s1);
    name.insert(name.size(), s2);
    return name;
}

9.47

#include <iostream>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
    const string s = "ab2c3d7R4E6";
    const string num = "012345678";
    string::size_type pos = 0;
    while((pos = s.find_first_of(num, pos)) != string::npos)
    {
        cout << s[pos] << " ";
        pos++;
    }
    cout << endl;
    pos = 0;
    while((pos = s.find_first_not_of(num, pos)) != string::npos)
    {
        cout << s[pos] << " ";
        pos++;
    }
    cout << endl;
    return 0;
}

9.48
string::npos

9.49

#include <iostream>
#include <string>
using namespace std;

const string s = "bdfghjklpqy";
string getWord(const string &word)
{
    string max, temp;
    string::size_type pos = 0;
    while ((pos = word.find_first_not_of(s, pos)) != string::npos)
    {
        temp = word.substr(pos, word.find_first_of(s, pos) - pos);
        if(temp.size() > max.size())
            max = temp;
        pos += temp.size();
    }
    return max;
}

int main(int argc, char *argv[])
{
    //好像理解错题目的意思了,反正是练习,我算的是求出字符串中最长的目的子串
    cout << getWord("hhhaahhhaaaaaaahhhhaaaaaaaacaah") <<endl;
    return 0;
}

9.50

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
    const vector<string> vec = {"10.1", "20","30", "40", "50"};
    int sum = 0;
    float sumf = 0;
    for(auto &x: vec)
        sum += stoi(x);
    cout << sum <<endl;
    for(auto &x: vec)
        sumf += stof(x);
    cout << sumf <<endl;
    return 0;
}

9.51
mytime.h

#ifndef PRO1_MYTIME_H
#define PRO1_MYTIME_H

#include <iostream>
#include <string>
#include <array>
using namespace std;
class mytime {
public:
    explicit mytime(const string &s = "");
    void print();
private:
    unsigned year;
    unsigned month;
    unsigned day;
    unsigned nameToMonth(const string& s);
    const array<string, 12> month_names{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
};

#endif //PRO1_MYTIME_H

mytime.cpp

#include "mytime.h"
mytime::mytime(const string &s)
{
    const string delimiters= " /,";
    auto posmonth = s.find_first_of(delimiters);
    month = nameToMonth(s.substr(0, posmonth));
    auto posday = s.find_first_of(delimiters, posmonth+1);
    day = (unsigned)stoi(s.substr(posmonth+1, posday-posmonth-1));
    year = (unsigned)stoi(s.substr(posday+1));
    if( !(day<=31 && day>=0 && month >=1 && month <=12) )
        throw invalid_argument("Error!!!!");
}
unsigned mytime::nameToMonth(const string &s)
{
    if(s.empty())
        return 0;
    if(isdigit(s[0]))
        return (unsigned)stoi(s);
    for(int i =0; i< 12; i++)
    {
        if(s.find(month_names[i]) != string::npos )
            return (unsigned)i+1;
    }
    return 0;
}
void mytime::print()
{
    cout << "year: " << year;
    cout << "  month: " << month;
    cout << "  day: "<< day << endl;
}

main.cpp

#include <iostream>
#include "mytime.h"
using namespace std;

int main(int argc, char *argv[])
{
    mytime time1("January,1,1990");
    mytime time2("1/1/1990");
    mytime time3("Jan 1 1990");
    time1.print();
    time2.print();
    time3.print();
    return 0;
}

9.52

#include <iostream>
#include <stack>
using namespace std;

int main(int argc, char *argv[])
{
    const string expr = "a()a(aaa(aaa(a)))aa()";
    const char placehold = '#';
    int num = 0;  // 栈中'('的个数
    stack<char> stk;
    for (auto c : expr)
    {
        stk.push(c);
        if (c == '(')
            ++num;
        if (num && c == ')')
        {
            while (stk.top() != '(')
                stk.pop();
            stk.pop();
            stk.push(placehold);
            --num;
        }
    }
    string s;
    while(!stk.empty())
    {
        s.insert(s.begin(),stk.top());
        stk.pop();
    }
    cout << s << endl;
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值