当前位置:   article > 正文

C++ Primer第9章(习题解答):顺序容器_c++primer练习9.6

c++primer练习9.6

9.1节,练习

9.1:对于下面的程序任务,vector,deque,和list那种容器最为适合?解释你的选择的理由。如果没有哪一种容器优于其他容器,也请解释理由。
(a) 读取固定数量的的单词,将他们按照字典序插入到容器中,我们将下一章看到,关联容器更加适合这个问题。
答:vector更好,vector支持随机访问,操作性更大
(b)读取未知数目的单词,总是将新单词插入到末尾。删除操作在末尾进行。
答:list更好,因为只针对删除的话链表的删除的效率还是十分之高的
(c ) 从一个文件读取未知数量的整数。将这些数排序,然后将他们打印到标准输出
答:vector更好,vector进行排序的效率较其他两种效率高
官方解答:
a:按字典序插入到容器中意味着进入插入排序操作,从而需要在容器内部进入插入排序工作,vector在尾部之外的插入和删除元素很慢,deque在头尾之外的位置删除和插入排序很慢,而list则适用于任何情况插入。但是如果是先装入然后利用sort排序,利用vector也可以。
b:由于需要频繁进行插入删除操作,于是选择deque或者list,如果需要频繁的随机访问,则为deque
c:由于整数占用空降很小,而且排序需要频繁随机访问,选择vector

9.2节练习

9.2:定义一个list对象,其元素类型为int的deque。
答:

list<deque<int>> mylist;
  • 1

9.3节练习

9.3构成迭代器范围的迭代器有何限制?
答:两个迭代器begin和end必须指向同一个容器中的元素或者是容器最后一个元素之后的位置,我们可以通过反复递增begin来达到end,end不在begin之前
9.4:编写程序,接受一对指向vector< int >的迭代器和一个int值,在两个迭代器指定的范围中查找给定的值,返回一个布尔值来指出是否找到
答:

#include <cstdio>
#include <iostream>
#include<vector>
using namespace std;
bool my_find(vector<int>::iterator first,vector<int>::iterator last,int num){
    while(first!=last){
        if(*first==num)
            return true;
        first++;
    }
    return false;
}
int main()
{
    //测试
    vector<int> test = {1, 2, 3, 4};
    cout << my_find(test.begin(), test.end(), 3) << endl;
    getchar();
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

9.5:重写上一题的程序,返回一个迭代器指向找到的元素,注意,程序
答:

#include <cstdio>
#include <iostream>
#include<vector>
using namespace std;
vector<int>::iterator my_find(vector<int>::iterator first,vector<int>::iterator last,int num){
    while(first!=last){
        if(*first==num)
            return first;
        first++;
    }
    return last;
}
int main()
{
    //测试
    vector<int> test = {1, 2, 3, 4};
    cout << *my_find(test.begin(), test.end(), 4) << endl;
    getchar();
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

9.6:下面的程序有何问题?你应该如何修改它?

list<int>lst1;
list<int>::iterator iter1=lst1.begin(),iter2=lst2.end();
while(iter1<iter2)/*...*/
  • 1
  • 2
  • 3

答:
迭代器不支持>和<,可以修改成while(iter1!=iter2)

9.2.2节练习

9.7:为了索引int的vector中元素,应该使用什么类型。
答:iterator
9.8:为了读取string的list中的元素,应该使用什么类型?如果写入list,又该使用什么类型?
答:value_type表示元素类型,可以读取、reference表示引用类型,可以写入
9.9:begin和cbegin有啥区别?
答:begin是普通的迭代器,可以改变容器元素,而cbegin是const begin,不可以改变容器元素
9.10:下面的4个对象分别是什么类型?

vector<int>vi;
const vector<int>v2;
auto it1=v1.begin(),it2=v2.begin();
auto it3=v1.cbegin(),it4=v2.cbegin();
  • 1
  • 2
  • 3
  • 4

答:it1:iterator it2:const iterator it3:const iterator it4: const iterator

9.2.4节练习

9.11:对于6种创建和初始化vector对象的方法,每一种都给出一个实例,解释每个vector包含什么值。
答:

vector<int>ans;//空
vector<int>ans(10);//10个值,每个值为0
vector<int>ans={1,2,3,4};//1,2,3,4
vector<int>ans(10,1);//10个值,每个值为1
vector<int>ans(ans1);//拷贝ans1中的元素
vector<int>ans(ans1.begin()+1,ans1.end());//初始化为两个迭代器指定范围的元素
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

9.12:对于接受一个容器创建其拷贝的构造函数,和接受两个迭代器创建拷贝的构造函数,解释它们的不同。
答:迭代器所拷贝的是其范围内的元素,而接受一个容器创建是全部元素
9.13:如何从一个list< int >初始化为一个vector< double>,从一个vector< int >又该如何创建?编写代码验证你的解答。
答:容器类型不同,所以采用范围初始化,vector< int > dvec(list.begin(),list.end()),从vector转化为vector< double >可采用容器初始化vector< double >devc=list

9.2.5节练习

9.14:将一个list中的char*指针(指向c风格字符串)元素赋值给vector中的string
答:由于char*类型不同于string但是可以转换成stirng所以可以利用范围赋值方式

9.2.7节练习

9.15:编写程序,判断两个vector< int >是否相等
答:类型和容器都相同,所以可以使用等于判断符

int main()
{
    //测试
    vector<int> test = {1, 2, 3, 4};
    vector<int> test1 = {1, 2, 3, 4};
    //cout << test == test1 << endl;
    int ret = test == test1;
    cout << ret << endl;
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

9.16:重写上一段的程序,比较一个list< int >中的元素和一个vector< int >中的元素
答:由于容器不同,所以需要使用范围内赋值方式,之后再通过等号关系符来进行比较

int main()
{
    //测试
    vector<int> test = {1, 2, 3, 4};
    vector<int> test1 = {1, 2, 3, 4};
    list<int> test2={1,2,3,4,5,6};
    vector<int> ans(test2.begin(), test2.end());
    int ret = ans == test1;
    cout << ret << endl;
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

9.17:假如c1和c2是两个容器,下面的比较操作有何限制(如果有的话)
if(c1<c2)
答:需要是同类型的容器,相同类型的元素,能支持<运算符

9.3.1节练习

9.18:编写程序,从标准输入读取string序列,存入一个deque中,编写一个循环,用迭代器打印deque中的元素。
答:

int main()
{
    //测试
    string line;
    deque<string> ans;//双端队列
    while(getline(cin,line)){
        ans.push_back(line);
    }
    for(auto &ans1:ans){
        cout << ans1 << " ";
    }
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

9.19:重写上面的程序,用list代替deque,列出程序中需要做出哪些改变。
答:

int main()
{
    //测试
    string line;
    list<string> ans;//双链表
    while(getline(cin,line)){
        ans.push_back(line);
    }
    for(auto &ans1:ans){
        cout << ans1 << " ";
    }
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

9.20:编写程序,从一个list< int >拷贝元素到两个deque中。值为偶数的所有元素都拷贝到一个deque中,而奇数值元素都拷贝到另一个deque中
答:

int main()
{
    //测试
    list<int> list1 = {1, 2, 3, 4, 5};
    deque<int> d1, d2;
    for(auto &ans:list1){
        if(ans%2){
            d1.push_back(ans);
        }else{
            d2.push_back(ans);
        }
    }
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

9.21:如果我们将第308页中使用insert返回值将元素添加到list中的循环改写为将元素插入到vector中,分析循环将如何工作
答:其循环就是当iter永远指向第一个元素,元素为零是则为空,然后造成其插入后元素的顺序与输入顺序相反
9.22:假定iv是一个int的vector,下面的程序存在什么情况?你将如何修改?

vector<int>::iterator iter=iv.begin(),mid=iv.begin()+iv.size()/2;
while(iter!=mid){
	if(*iter==some_val)
		iv.insert(iter,2*some_val);
}
  • 1
  • 2
  • 3
  • 4
  • 5

答:迭代器没有增加,不会到中间节点,然后对于vector,deque,string容器直接加入是会使迭代器,指针,引用失效

int main()
{
    //测试
    vector<int> iv = {1, 2, 3, 4};
    int some_val = 2;
    int this_size = iv.size();
    int count = 0;
    vector<int>::iterator iter = iv.begin(), mid = iv.begin() + this_size / 2+count;
    while (iter != iv.begin() + this_size / 2+count)
    {
        if (*iter == some_val){
            iter=iv.insert(iter, 2 * some_val);
            iter++;
            iter++;
            count++;
        }else{
            iter++;
        }
        
    }
    for(auto &ans:iv){
        cout << ans << " ";
    }
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

9.3.2节练习

9.23:在本节第一个程序(309页),若c.size()为1,则val1,val2,val3,val4值为多少?
答:值都是第一个元素
9.24:编写程序,分别使用at,下标运算符、front何begin提取一个vector中的第一个元素。在一个空的vector上测试你的程序。
答:

程序会异常终止,因为使用at运算,超出范围返回会抛出out_of_range异常
int main()
{
    vector<int> test;
    cout << test.at(0) << endl;
    cout << test[0] << endl;
    cout << test.front() << endl;
    cout << *test.begin() << endl;
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

9.3.3节练习

9.25:对于312页中删除一个范围内的元素的程序,如果elem1与elem2相等会发生什么,如果elem2是尾后迭代器,或者elem1和elem2皆为尾后迭代器,又会发生什么
答:则一个元素也删除不了
9.26:使用下面代码定义的ia,将ia拷贝到一个vector和一个list中。使用单迭代版本的erase从list中删除元素,从vector中删除偶数元素。
答:

#include <cstdio>
#include <iostream>
#include<vector>
#include<string>
#include<deque>
#include<list>
using namespace std;
vector<int>::iterator my_find(vector<int>::iterator first,vector<int>::iterator last,int num){
    while(first!=last){
        if(*first==num)
            return first;
        first++;
    }
    return last;
}
int main()
{
    int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
    vector<int> ivec;
    for(auto &val:ia){
        ivec.emplace_back(val);
    }
    list<int> list1(ivec.begin(), ivec.end());
    for (auto iv = ivec.begin();iv!=ivec.end();){
        if((*iv)&1)
            ;
        else{
            iv=ivec.erase(iv);
            continue;
        }
        iv++;
    }
    for (auto iv = list1.begin();iv!=list1.end();){
        if((*iv)&1){
            iv=list1.erase(iv);
            continue;
        }
        iv++;
    }
    for(auto &ans:list1){
        cout << ans << " ";
    }
    for(auto &ans:ivec){
        cout << ans << " ";
    }
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

9.3.4节练习

9.27:编写程序,查找程序并删除forward_list< int>中的奇数元素
答:

#include <cstdio>
#include <iostream>
#include<vector>
#include<string>
#include<deque>
#include<list>
#include<forward_list>
using namespace std;
vector<int>::iterator my_find(vector<int>::iterator first,vector<int>::iterator last,int num){
    while(first!=last){
        if(*first==num)
            return first;
        first++;
    }
    return last;
}
int main()
{
    forward_list<int> list1 = {1, 2, 3, 4, 5, 6};
    auto pre = list1.before_begin();
    auto curr = list1.begin();
    while(curr!=list1.end()){
        if(*curr&1){
            curr = list1.erase_after(pre);
        }else{
            pre = curr;
            ++curr;
        }
    }
    for(auto &ans:list1){
        cout << ans << " ";
    }
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

9.28:编写函数,接受一个forward_list< string >和两个string共三个参数。函数应该在链表中查找一个string,并将第二个string插入到紧接着第一个string之后的位置。若第一个string未在链表中,则将第二个string插入到来链表中
答:

#include <cstdio>
#include <iostream>
#include<vector>
#include<string>
#include<deque>
#include<list>
#include<forward_list>
using namespace std;
void my_insert(forward_list<string>&l1,string s1,string s2){
    for (auto curr = l1.begin(); curr != l1.end();++curr){
        if(*curr==s1){
            l1.insert_after(curr, s2);
            return;
        }
    }
}
int main()
{
    forward_list<string> l1 = {"1", "2", "3", "4"};
    my_insert(l1, "3", "5");
    for(auto &ans:l1){
        cout << ans << " ";
    }
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

9.3.5节练习

9.29:假定vec包含25个元素,那么vec.resize(100)会做什么?接下来调用vec.resize(10)会发生什么。
答:会将其元素扩到100个元素,然后其余的75个元素为0,接下来会发生截断,即只剩下前10个元素
9.30:接受单个元素的resize版本对元素类型有什么限制(如果有的话)
答:如果元素是类类型,则单参数resize版本要求该类型必须提供一个默认构造函数

9.3.6节练习

9.31:第316页中删除偶数值并复制奇数值元素的程序不能用于list或者forward_list。为什么?修改程序,使之能用于这些程序。
答:由于list和forward_list是链表,所以如果要插入值,必须要其前驱,并且没有对于链表没有insert函数

#include <cstdio>
#include <iostream>
#include<vector>
#include<string>
#include<deque>
#include<list>
#include<forward_list>
using namespace std;
int main()
{
    forward_list<int> l1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    auto pre = l1.before_begin();
    auto curr = l1.begin();
    while(curr!=l1.end()){
        if(*curr&1){
            curr = l1.insert_after(curr, *curr);
            pre = curr;
            curr++;
        }else{
            curr = l1.erase_after(pre);
        }
    }
    for(auto &ans:l1){
        cout << ans << " ";
    }
    getchar();
    
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

9.32:在第316页中程序中,向下面语句这样调用insert是否合法,如果不合法,为什么?

iter=vi.insert(iter,*iter++)
  • 1

答:很多编译器对实参求值,向形参传递的处理顺序是由右向左的。这意味这编译器在在编译上述代码时,首先对*iter++求值,传递的第一个参数的迭代器指向的是错误位置。
9.33:在本节的最后一个例子中,如果不将insert的结果赋予begin,将会发生什么?编写程序,去掉赋值语句,验证你的答案。
答:插入操作会导致迭代器失效,所以必须赋值
9.34:假定vi是一个保存int的容器,其中有偶数值也有奇数值,分析下面循环的行为,然后编写程序来验证你的分析是否正确。

iter=vi.begin();
while(iter!=vi.end())
	if(*iter%2)
		iter=vi.insert(iter,*iter);
	++iter;
  • 1
  • 2
  • 3
  • 4
  • 5

答:

#include <cstdio>
#include <iostream>
#include<vector>
#include<string>
#include<deque>
#include<list>
#include<forward_list>
using namespace std;
int main()
{
    vector<int> vi = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    auto iter=vi.begin();
    while(iter!=vi.end()){
	    if(*iter%2){
            iter=vi.insert(iter,*iter);
            ++iter;
        }
        ++iter;
        cout << *iter << " ";
    }
    for(auto &ans:vi){
        cout << ans << " ";
    }
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

9.4节练习

9.35:解释一个vector的capacity和size有何区别
答:capacity代表分配给容器内存的元素个数,而size代表现在容器中元素的个数
9.36:一个容器的capacity可能小于它的size吗?
答:基本上不可能
9.37:为什么list或者array没有capasity成员函数?
答:array容器是因为其大小已经固定,不可增加和减少,而list是由于是链表,每增加一个元素就会增加对应大小的内存
9.38:编写程序,探究在你的标准库中,vector是如何增长的。
答:

 #include <cstdio>
#include <iostream>
#include<vector>
#include<string>
#include<deque>
#include<list>
#include<forward_list>
using namespace std;
int main()
{
    vector<int> vi;
    int s, c;
    for(s=vi.size(),c=vi.capacity();s<=c;s++){
        vi.push_back(1);
    }
     cout << "空间:" << vi.capacity() << "元素数" << vi.size() << endl;
      for(s=vi.size(),c=vi.capacity();s<=c;s++){
        vi.push_back(1);
    }
     cout << "空间:" << vi.capacity() << "元素数" << vi.size() << endl;
      for(s=vi.size(),c=vi.capacity();s<=c;s++){
        vi.push_back(1);
    }
     cout << "空间:" << vi.capacity() << "元素数" << vi.size() << endl;
      for(s=vi.size(),c=vi.capacity();s<=c;s++){
        vi.push_back(1);
    }
     cout << "空间:" << vi.capacity() << "元素数" << vi.size() << endl;
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

9.39:解释下面的程序片段做了什么:

vector<string>svec;
sevc.reserve(1024);
string word;
while(cin>>word)
	svec.push_back(word);
sevc.resize(svec.size()+svec.size()/2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

答:将输入的字符串加入容器中,之后等结束输入或者超出其容器的范围后再重置容器的大小
9.40:如果上一题中的程序读入256个单词,在resize之后容器的capacity可能是多少?如果读入了512个单词,1000个或者是1048个单词呢?
答:256是384,512是768,1000是2048,1048是2048

9.5.1节练习

9.41:编写程序,从一个vector< char >初始化为string
答:

    vector<char> ivec = {'1', '2', '3', '4'};
    string s(ivec.begin(), ivec.end());
  • 1
  • 2

9.42:假定你需要每次读取一个字符存入一个string中,而且知道最少需要读取100个字符,应该如何提高性能。
答:可以先用reserve为其预先分配100个空间,然后利用push_back来加入字符
9.43:编写一个函数,接受三个string参数s,oldVal和newVal。使用迭代器以及inset和erase函数将s中所有oldVal替换成newVal.测试你的程序,用它替换通用的简写形式,如,将"tho"替换成"though",将"thru"替换成"through"
答:

#include<string>
#include<vector>
#include<iostream>
using namespace std;
void my_replace(string &s,string &oldVal,string &newVal){
   int count = 0;
   for (auto begin = s.begin(); begin != s.end();begin++,count++){
       if(*begin==oldVal[0]){
           auto a = begin;
           int k = 0;
           bool flag = true;
           while(a!=s.end()&&k<oldVal.size()){
                   if(*a!=oldVal[k]){
                       flag = false;
                   }
                   ++a;
                   ++k;
           }
           if(flag){
               s.erase(count, k);
               s.insert(count, newVal);
           }
           begin = a;
       }
   }
}
int main()
{
   string a = "th i sd ";
   string b = "though";
   string c = "th";
   my_replace(a, c, b);
   cout << a << endl;
   getchar();
   getchar();
   return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

9.44:重写上一题的程序,这次使用一个下标和replace
答;

#include<string>
#include<vector>
#include<iostream>
using namespace std;
void my_replace(string &s,string &oldVal,string &newVal){
    int count = 0;
    for (int i=0; i<s.size();i++,count++){
        if(s[i]==oldVal[0]){
            int k = 0;
            int a = i;
            bool flag = true;
            while(a<s.size()&&k<oldVal.size()){
                    if(s[a]!=oldVal[k]){
                        flag = false;
                    }
                    ++a;
                    ++k;
            }
            if(flag){
                s.replace(i, k, newVal);
            }
        }
    }
}
int main()
{
    string a = "th i sd ";
    string b = "though";
    string c = "th";
    my_replace(a, c, b);
    cout << a << endl;
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

9.45:编写一个函数,接受一个表示名字的string参数和两个表示前缀如(“Mr")和后缀如(“Jr.")的字符串。使用迭代器及insert和append函数将前缀和后缀添加到给定的名字中,将生成新的string返回。
答;

string my_add(string &name,string prefix,string tailfix){
    name.insert(0, prefix);
    name.append(tailfix);
    return name;
}
  • 1
  • 2
  • 3
  • 4
  • 5

9.46:重写上一题的函数,这次使用的位置和长度来管理,并且只使用insert
答:

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";
	name_string(s,"Mr.","II");
	cout<<s<<endl;
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

9.47:首先查找stirng”ab2c3d7r4e6"中的每个数字字符,然后查找字母字符,编写两个版本的程序,第一要使用find_first_of,第二个要使用find_first_not_of
答:

//主要函数
void find_char(string &s,const string &word ){
    string::size_type pos=0;
    while((pos=s.find_first_of(word,pos))!=string::npos){
        cout << "位置:" << pos << "值:" << s[pos] << endl;
        ++pos;
    }
}
void find_char2(string&s,const string &word){
    string ::size_type pos = 0;
    while((pos=s.find_first_not_of(word,pos))!=string::npos){
        cout << "位置:" << pos << "值:" << s[pos] << endl;
        ++pos;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

9.48:假如name和numbers的定义如325页所示numbers.find(name)返回结果如何
答:由于找不到,所以返回为npos
9.49:如果一个字母延申到中线之上,如d或f则称其为有上出头部分如果一个字母延伸到中线一下,如p或g则称为下出头部分,编写程序读入一个单词文件,输出最长的不包含上出头以及下出头部分的单词
答:

void find_longest_string(ifstream &in){
    string word, longest_word;
    int max_length = 0;
    while(in>>word){
        if(word.find_first_of("bdfghjklpqty")!=string::npos)
            continue;
        if(word.size()>max_length){
            max_length = word.size();
            longest_word = word;
        }
    }
    cout << "最长不上头不下头单词为:" << longest_word << endl;
    return;
}
int main()
{
    string file = "D:\\data.txt";
    ifstream input(file);
    find_longest_string(input);
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

9.5.5节练习

9.50:编写程序处理一个vector< string >,其元素表示整数值。计算vector中所有元素之和。修改程序,使之计算表示浮点数值的string之和
答:

int main()
{
    vector<string> ivec = {"1", "2", "3", "4"};
    double sum = 0;
    for(auto &ans:ivec){
        sum += stod(ans);//转换成浮点数
    }
    cout << sum << endl;
    getchar();
    getchar();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

9.51:设计一个类,它有三个unsigned成员,分别表示年月日,为其编写构造函数,接受一个表示日期的string参数。你的构造函数应该能够处理不同的数据格式。如January 1,1900,1/1/1900 Jan 1 1900等
9.52:使用stack处理括号化的表达式,当你看到一个左括号,将其记录下来,当你在左括号之后看到一个右括号,从stack中pop对象,直到遇到左括号,将左括号页一起弹出栈。然后将一个值(括号内的运算结果)push到栈中,表示一个括号内的表达式已经处理完毕,被其运算结果所代替。
答:对于这两题的难度都比较大,是一次综合的运用,我就单独写上去放到我的c/c++专栏上,并且尽量让其结构比较完整。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/178215
推荐阅读
相关标签
  

闽ICP备14008679号