C++Primer_课后习题第九章

本文答案,部分参考于C++ Primer 习题集

前面章节的习题答案

第一章

第二章

第三章

第四章

第五章

第六章

第七章

第八章

9.1

(a)

按字典序插入到容器中,意味着进行插入排序操作,从而需要在容器内部频繁进行插入操作,vector在尾部之外的位置插入和删除元素很慢,deque 在头尾之外的位置插入和删除元素很慢.而list在任何位置插入和删除速度都很快.因此,这个任务选择list更为合适.当然,如果不是必须边读取单词边插入到容器中.可以使用vector,将读入的单词一次追加到尾部,读取完毕后,调用标准库到排序算法将到此重排为字典序.

(b)

由于需要在头,尾.分别进行插入,删除操作,因此将vecotor排除在外.

deque和list都可以达到很好的性能.如果还需要频繁进行随机访问,则deque更好.

©

由于整数占用空间很小.且快速的排序算法需频繁随机访问元素,将list排除在外,由于无需在头部进行插入,删除操作.因此使用vector即可.无须使用deque.

9.2

list> a;

9.3

两个迭代器begin和end必须指向同一个元素中的元素,或者是容器最后一个元素之后的位置,而且,对begin反复进行递增操作,可保证达到end,即end不在begin之前.

9.4

#include
#include
#include
#include
using namespace std;
bool Find(vector::iterator beg, vector::iterator end, int val);
int main() {
    vector a{ 1, 2, 3, 4, 5 };
    bool result = Find(a.begin(), a.end(), 1);
    if (result)
        cout << "True";
    else
        cout << "False";
    return 0;
}
bool Find(vector::iterator beg, vector::iterator end, int val) {
    while (beg != end) {
        if (val == *beg) {
            return true;
        }
        beg++;
    }
    return false;
}

9.5

#include
#include
#include
#include
using namespace std;
vector::iterator Find(vector::iterator beg, vector::iterator end, int val);
int main() {
    vector a{ 1, 2, 3, 4, 5 };
    vector::iterator result = Find(a.begin(), a.end(), 9);
    if (result == a.end()) {
        cout << "False";
    }
    else
        cout << "True";
    return 0;
}
vector::iterator  Find(vector::iterator beg, vector::iterator end, int val) {
    while (beg != end) {
        if (val == *beg) {
            return beg;
        }
        beg++;
    }
    return end;
}

9.6

错误的地方在于.

没有理解这几种容器的结构特点

list容器是不支持 <运算的

list 容器只支持 递增,递减 == 和 != 运算.

9.7

vector::iterator 

9.8

list::value_type
list::reference

9.9

cbegin() 不可以执行写操作

9.10

v1 就是普通的int vector
v2 就是常量的int vector 不能执行写操作
it1是普通的迭代器 可以执行写操作
it2,it3,it4都是const 迭代器,都不能执行写操作

9.11

    vector a1;
    vector a2(10);
    vector a3 = a1; vector a8(a1);
    vector a4{ 1,2,3,4 };vector a5 = { 1,2,3,4 };
    vector a6(10, 0);
    vector a7(a6.begin(), a6.begin() + 3);
    vector a9(7);

9.12

前一种完整

后一种灵活

9.13

这是自己写的脑瘫方法

#include
#include
#include
#include
using namespace std;

int main(){
    list a{1,2,3,4,5};
    vector b;
    for(auto t:a){
        double x=(double)t;
        b.push_back(x);
    }
    for(auto t:b){
        cout< c{1,2,3,4,5};
    vector d;
    for(auto t:c){
        double x=(double)t;
        d.push_back(x);
    }
    for(auto t:d){
        cout<

这是教科书上的方法

#include
#include
#include
using namespace std;

int main(){
    list  ilist={1,2,3,4,5,6,7};
    vector ivec={7,6,5,4,3,2,1};
    
    vector dvec(ilist.begin(),ilist.end());
    vector dvecl(ivec.begin(),ivec.end());

    cout<

9.14

#include
#include
#include
#include
using namespace std;

int main() {
    vector a;
    listb = {"I","will", "Become", "rich", "and", "Stronger", "and", "With", "abs" };
    a.assign(b.begin(), b.end());
    for(auto t:a){
        cout<

9.15

#include
#include
#include
#include
using namespace std;

int main() {
    vectora={1,2,3,4},b={2,3,4,5};
    if(a>b)
        cout<<"a>b";
    else if(a

9.16

#include
#include
#include
#include
using namespace std;
bool i_v_equal(vector &ivec,list &ilist){
    //比较list和vector元素的个数
    if(ilist.size()!=ivec.size())
        return false;
    auto lb=ilist.cbegin();         //list首元素
    auto le=ilist.cend();           //list尾元素
    auto vb=ivec.cbegin();          //vector首元素
    for(;lb!=le;lb++,vb++)
        if(*lb!=*vb)
            return false;
    return true;
}
int main(){
    vector ivec={1,2,3,4,5,6,7};
    list ilist={1,2,3,4,5,6,7};
    list ilist1={1,2,3,4,5};
    list ilist2={1,2,3,4,5,6,8};
    list ilist3={1,2,3,4,5,7,6};
    cout<

9.17

① 容器类型必须相同,元素类型也必须相同

② 元素类型必须支持 < 运算符

9.18

#include
#include
#include
#include
#include
using namespace std;
int main(){
    string a; 
    deque  b;
    while(cin>>a){
        b.push_back(a);
    }
    deque::iterator begin=b.begin();
    deque::iterator end=b.end();
    while(begin!=end){
        cout<<*begin<

9.19

#include
#include
#include
#include
#include
using namespace std;
int main(){
    string a; 
    list  b;
    while(cin>>a){
        b.push_back(a);
    }
    list::iterator begin=b.begin();
    list::iterator end=b.end();
    while(begin!=end){
        cout<<*begin<

9.20

#include
#include
#include
#include
#include
using namespace std;
int main(){
    int a; 
    list  b;
    while(cin>>a){
        b.push_back(a);
    }
    list::iterator begin=b.begin();
    list::iterator end=b.end();
    deque even;    //偶数
    deque odd;     //奇数
    while(begin!=end){
        cout<<*begin<

9.21

效果其实是一样的。

但是在vector中,只有不是push_back 就是插入到尾部,

别的插入也都是可以的.

但是速度会很慢.

9.22

① 向一个vector,string,deque插入元素.会使现有指向容器的迭代器失效.

② 其次,练习如何利用insert返回的迭代器,使得在向容器插入元素后,仍能正确的在容器中遍历.

解法一:

#include
#include
using namespace std;
int main(void){
    vector iv={1,1,2,1};
    int some_val=1;
    vector::iterator iter=iv.begin();
    int org_size=iv.size(),new_ele=0;       //原大小和新元素个数
    //每个循环步都重新计算 "mid",保证指向iv原中央元素
    while(iter!=(iv.begin()+org_size/2+new_ele))
        if(*iter==some_val){
            iter=iv.insert(iter,2*some_val);    //iter指向新元素
            new_ele++;
            iter++;iter++;                      //吧tier推进到旧元素的下一个位置
        }else iter++;                           //简单推进iter
        //用begin()获取vector首元素迭代器,遍历vector中的所有元素
        for(iter=iv.begin();iter!=iv.end();iter++)
            cout<<*iter<

解法二:

#include
#include
using namespace std;
int main(void){
    vector iv={1,1,2,1};
    int some_val=1;
    vector::iterator iter=iv.begin();
    int org_size=iv.size(),i=0;     //原大小
    //用循环变量控制循环次数
    while(i<=org_size/2){
        if(*iter==some_val){
            iter=iv.insert(iter,2*some_val);
            iter++;iter++;
        }else iter++;
        i++;
    }
    //用begin()获取vector首元素迭代器,遍历vector中的所有元素
    for(iter=iv.begin();iter!=iv.end();iter++)
        cout<<*iter<

9.23

四个值都一样,都等于容器中第一个元素的指.

9.24

#include
#include
using namespace std;
int main(void){
    vector a;
    cout<<*a.begin();
    cout<

结果如下:

在这里插入图片描述

9.25

① 当两个迭代器相等时

#include
#include
using namespace std;
int main(void){
    vector a={1,2,3,4,5};
    a.erase(a.begin(),a.begin());
    for(auto i:a){
        cout<

② 当elem1和elem2都是尾后迭代器时

会报错!!!

具体原因没有找到,我翻了一哈,官网的代码说明,没有找到解释,

但是在我自己的环境里写了,会报错.

③ 当elem2是尾后迭代器时

一样的报错.

9.26

#include
#include
#include
using namespace std;
int main(void){
    int ia[]={0,1,1,2,3,5,8,13,21,55,89};
    vector iv;
    list il;

    iv.assign(ia,ia+11);
    il.assign(ia,ia+11);

    vector:: iterator iiv=iv.begin();
    while(iiv!=iv.end()){
        if(!(*iiv&1))
            iiv=iv.erase(iiv);
        else iiv++;
    }

    list:: iterator iil=il.begin();
    while(iil!=il.end()){
        if(!(*iil&1))
            iil=il.erase(iil);
        else iil++;
    }

    for(auto i:iv){
        cout<

9.27

#include
#include
#include
#include
using namespace std;
int main(void){
    forward_list flst={0,1,2,3,4,5,6,7,8,9};
    auto prev=flst.before_begin();
    auto curr=flst.begin();
    while(curr!=flst.end()){
        if(*curr%2)
            curr=flst.erase_after(prev);
        else{
            prev=curr;
            ++curr;
        }
    }
    for(auto i:flst){
        cout<

9.28

#include
#include
#include
using namespace std;
void forwar_list_insert(forward_list &, string, string);
int main(void) {
    forward_list flst = { "Money","Power","Girl","Desire" };
    forwar_list_insert(flst, "Power", "Wife");
    //输出
    for (auto i : flst) {
        cout << i << " ";
    }
    cout << endl;
}
void forwar_list_insert(forward_list& flst, string find_string, string insert_string) {
    auto curr = flst.begin();
    auto prev = flst.before_begin();
    while (curr != flst.end()) {
        if (*curr == find_string) {
            flst.insert_after(curr, insert_string);
            return;
        }
        else {
            prev = curr;
            ++curr;
        }
    }
    flst.insert_after(prev, insert_string);
    return;
}

C++Primer_课后习题第九章_第1张图片

C++Primer_课后习题第九章_第2张图片

9.29

会自动填充75个值,值的内容要看vec的类型

resize(10) 会删除后面的90个元素

9.30

对于元素是类类型,则单参数resize版本要求该类型必须提供一个默认构造函数

9.31

forward_list的改法

#include
#include
#include
#include
using namespace std;

int main(void) {
    forward_list llist = { 0,1,2,3,4,5,6,7,8,9 };
    auto iter = llist.begin();
    auto iter_before = llist.before_begin();
    while (iter != llist.end()) {
        if (*iter % 2 == 0) {
            iter=llist.erase_after(iter_before);
        }
        else {
            llist.insert_after(iter_before, *iter);
            iter_before = iter;
            ++iter;
        }
    }
    for (auto i : llist) {
        cout << i << " ";
    }
    cout << endl;
}

list的代码

#include
#include
#include
#include
using namespace std;

int main(void) {
    list llist = { 0,1,2,3,4,5,6,7,8,9 };
    auto iter = llist.begin();
    while (iter != llist.end()) {
        if (*iter % 2 == 0) {
            iter=llist.erase(iter);
        }
        else {
            iter=llist.insert(iter, *iter);
            ++iter;
            ++iter;
        }
    }
    for (auto i : llist) {
        cout << i << " ";
    }
    cout << endl;
}

9.32

不建议这样写,因为在表示式中调用这个变量,而且结果和中间都有的话,其实是看编译器的.这样写有很大机率出错.

9.33

插入元素会让begin()失效

如果不赋予的话,这个代码会报错.

9.34

会陷入死循环中

代码如下:

#include
#include
#include
#include
using namespace std;

int main(void) {
    list llist = { 0,1,2,3,4,5,6,7,8,9 };
    auto iter = llist.begin();
    while (iter != llist.end()) {
        if (*iter % 2 ) 
            iter=llist.insert(iter, *iter);
        ++iter;
    }

    for (auto i : llist) {
        cout << i << " ";
    }
    cout << endl;
}

9.35

capacity返回已经为vector分配了多大内存空间(单位是元素大小),也就是在不分配新空间的情况下,容器可以保存多少个元素,而size则返回容器当前已经保存了多少个元素

9.36

不可能的

9.37

list是链表,当有新元素加入时,会从内存空间分配一个新节点保存它,当从链表删除元素时,该节点占用的内存空间会被立即释放,因此,一个链表占用的内存空间总是与它保存的元素所需空间相等(换句话说,capacity总是等于size)

而array是固定大小数组,内存一次性分配,大小不变,不会变化.

因此他们均不需要capacity.

9.38

#include
#include
#include
#include
#include
using namespace std;

int main(void) {
    vector vlist={0,1,2,3,4,5,6,7,8,9};
    cout<<"size:"<

结果如下:

C++Primer_课后习题第九章_第3张图片

9.39

一开始就开辟了1024个svec的空间 有1024个string

默认初始化为空串

然后再输入若干字符串

然后再调整大小为

输入大小+输入大小的一半=输入大小的1.5倍

9.40

比384多

比768多

比1500多

比1572多

答案上的解释(我没有试过)

384

768

2048

2048

9.41

#include
#include
#include
#include
#include
using namespace std;

int main(void) {
    vector vc={'H','e','l','l','o'};
    string s(vc.data(),vc.size());
    cout<

9.42

#include
#include
#include
#include
#include
using namespace std;
void input_string(string &s){
    s.reserve(100);
    char c;
    while(cin>>c)
        s.push_back(c);
}
int main(void) {
    string s;
    input_string(s);
    cout<

9.43

#include
#include
#include
#include
#include
using namespace std;
void replace_string(string &s,const string &oldVal,const string &newVal){
    auto l=oldVal.size();
    if(!l)
        return ;                                        //要查找的字符串为空的情况
    
    auto iter=s.begin();
    while(iter<=s.end()-1){                             //末尾少于oldVal长度的部分无须检查
        auto iter1=iter;
        auto iter2=oldVal.begin();
        //s中iter开始的子串必须每个字符都与oldVal相同
        while(iter2!=oldVal.end()&& *iter1==*iter2){
            ++iter1;
            ++iter2;
        }
        if(iter2==oldVal.end()){
            iter=s.erase(iter,iter1);
            if(newVal.size()){
                iter2=newVal.end();
                do{
                    iter2--;
                    iter=s.insert(iter,*iter2);
                }while(iter2>newVal.begin());
            }
            iter+=newVal.size();
        }else iter++;
    }
}
int main(){
    string s="tho thru tho!";
    replace_string(s,"thru","throught");
    cout<

9.44

#include
#include
#include
using namespace std;
void replace_string(string &s,const string &oldVal,const string &newVal){
    int p=0;
    while(p=s.find(oldVal,p)!=string::npos){
        s.replace(p,oldVal.size(),newVal);
        p+=newVal.size();
    }
}
int main(){
    string s="tho thru tho!";
    replace_string(s,"thru","throught");
    cout<

9.45

#include
#include
#include
using namespace std;
void name_string(string &name,const string &prefix,const string &suffix){
    name.insert(name.begin(),1,' ');
    name.insert(name.begin(),prefix.begin(),prefix.end());
    name.append(" ");
    name.append(suffix.begin(),suffix.end());
}
int main(){
    string s="James Bond";
    name_string(s,"Mr.","II");
    cout<

9.46

#include
#include
#include
using namespace std;
void name_string(string &name,const string &prefix,const string &suffix){
    name.insert(0," ");
    name.insert(0,prefix);
    name.insert(name.size()," ");
    name.insert(name.size(),suffix);
}
int main(){
    string s="James Bond";
    name_string(s,"Mr.","II");
    cout<

9.47

使用find_first_of

#include
#include
#include
using namespace std;
int main(){
    string index="ab2c3d7R4E6";
    index.find_first_of("1");
    vector Num={'0','1','2','3','4','5','6','7','8','9'};
    for(int i=0;i<=9;i++){
        if(index.find_first_of(Num[i])!=string::npos){
            cout<

使用not

#include
#include
using namespace std;
void find_not_char(string &s,const string &chars){
    cout<<"在"<

9.48

会返回

string::npos

因为找不到

9.49

#include
#include
#include
using namespace std;
void find_longest_word(ifstream &in){
    string s,longest_word;
    int max_length=0;
    while(in>>s){
        if(s.find_first_of("bdfghjklpqty")!=string::npos)
            continue;
        cout<

9.50

整数

#include
#include
#include
#include
using namespace std;
int main(){
    vector index={"1","2","3","4","5","6"};
    int sum=0;
    for(auto i:index){
        sum+=stoi(i);
    }
    cout<
21
请按任意键继续. . .

浮点数

#include
#include
#include
#include
using namespace std;
int main(){
    vector index={"1.90","2.85","3","4","5","6"};
    double sum=0;
    for(auto i:index){
        sum+=stod(i);
    }
    cout<
22.75
请按任意键继续. .

9.51

C++Primer_课后习题第九章_第4张图片

C++Primer_课后习题第九章_第5张图片

C++Primer_课后习题第九章_第6张图片

C++Primer_课后习题第九章_第7张图片

C++Primer_课后习题第九章_第8张图片

C++Primer_课后习题第九章_第9张图片

C++Primer_课后习题第九章_第10张图片

9.52

C++Primer_课后习题第九章_第11张图片

C++Primer_课后习题第九章_第12张图片

C++Primer_课后习题第九章_第13张图片

C++Primer_课后习题第九章_第14张图片

导图

C++Primer_课后习题第九章_第15张图片

你可能感兴趣的:(C++,Primer)