C++ Primer 【第四版】第九章 顺序容器

来源:互联网 发布:流行朋克知乎 编辑:程序博客网 时间:2024/05/16 06:55

1.解释下列初始化,指出哪些是错误的,为什么?

intia[7] = { 0, 1, 1, 2, 3, 5, 8 };

stringsa[6] = {

        “Fort Sunter”, “Manassas”,“Perryville”,  “ Vicksburg”, “Meridian”,“Chancellorsville” };

(a)vector<string> svec( sa, sa+6 );

(b)list<int> ilist( ia + 4, ia + 6 );

(c)vector<int> ivec( ia, ia + 8 );

(d)list<string> slist ( sa + 6, sa );

(c)错误,初始化迭代器的终止指针访问数组越界。

(d)错误,初始化容器的迭代器起始点和终止点指定错误,顺序反了。

 

2.创建和初始化一个vector对象有4种方式,为每种方式提供一个例子,并解释每个例子生成的vector对象包含什么值。

int ia[3] = { 1, 2, 3 };

(1) vector<int> ivec1( 3 ); //默认初始化,内容为30

(2) vector<int> ivec2( ia, ia+3); //把数组ia里的值复制到 ivec2

(3) vector<int> ivec3 ( ivec2 ); //ivec2来初始化 ivec3

(4) vector<int> ivec4 ( 3, 6 ); // ivec4初始化为36

 

3.解释复制容器对象的构造函数和使用两个迭代器的构造函数之间的差别。

前者的构造函数将一个对象的全部元素复制到另一个容器对象里,而且要求两个对象的类型和元素的类型都相同;

后者可以将一个容器初始化为另一个容器的子序列,而且不要求两个容器的类型是同类型的。

 

 

4.定义一个list对象来存储deque对象,该对象存放int类型的元素。

list< deque<int> > ilist;

 

5.为什么我们不可以使用容器来存储iostream对象?

 

因为iostream对象不支持复制和赋值操作。

 

6.假设有一个名为Foo的类,这个类没有定义默认构造函数,但提供了需要一个int型参数的构造函数。定义一个存放Foolist对象,该对象有10个元素。

list<Foo> Flist( 10, 1 );

 

 

7.下面的程序错在哪里?如何改正?

list<int>lst1;

list<int>::iteratoriter1 = lst1.begin(), iter2 = lst1.end();

while( iter1 < iter2 ) /*…*/

错在while循环里的条件表达式使用了<操作符,因为list容器的迭代器不支持关系操作符,可改为 iter1 !=iter2

 

 

 

8.假设vec_iter绑定到vector对象的一个元素,该vector对象存放string类型的元素,请问下面的语句实现什么功能?

it( vec_iter->empty() ) //…

判断vec_iter所指向的vector元素是否为空字符串。

 

 

 

9.编写一个循环将list容器的元素逆序输出。

list<int> ilist( 10, 1 );

list<int>::iterator it = ilist. end();

--it;

for ( ; it != ilist.begin(); --it )

        cout << *it<< endl;

 

 

 

10.下列迭代器的用法哪些是错误的?

constvector< int > ivec ( 10 );

vector< string > svec ( 10 );

list<int > ilist( 10 );

(a)vector<int>::iterator it = ivec.begin();

(b)list<int>::iterator it = ilist.begin() + 2;

(c)vector<string>::iterator it = &svec[0];

(d)for ( vector<string>::iterator it= svec.begin(); it != 0; ++it )  //…

(b)错误,list的迭代器不支持算术运算。

(a)错,ivec.begin()返回的是const vector<int>的迭代器,不能用来初始化vector<int>的迭代器。

(c)错误,迭代器不支持用&操作符来初始化。

(d)错误,it0进行比较会产生运行时错误。

 

11.要标记出有效的迭代器范围,迭代器需满足什么约束?

firstlast须指向同一个容器中的元素或超出末端的下一位置。last不能位于first之前。

 

 

 

12.编写一个函数,其形参是一对迭代器和一个int型数值,实现在迭代器标记的范围内寻找该int型数值的功能,并返回一个bool结果,以指明是否找到指定数据。

//11.15_9.12_iterator_Function.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<vector>

#include<cassert>

usingnamespace std;

 

typedefvector<int>::iterator iter;

boolfindTheInt( iterfirst, iter last, int x )

{

        assert(first <=last);

        if ( first >last )

                  cout<< " iterator error."<<endl;

        for ( iterit = first; it != last; ++it )

        {

                  if( *it ==x )

                           return true;

        }

        return false;

}

 

int_tmain(int argc, _TCHAR* argv[])

{

        int ia[] = { 0, 1, 2, 3, 4, 5 };

        vector<int>ivec( ia, ia+5 );

        bool find3 =false;

        find3= findTheInt(ivec.begin(), ivec.end(), 3 );

        if ( find3 )

        {                                                                                                              

                  cout<< " We got 3 in ia[]."<<endl;

        }

        else

                  cout<< " There is not 3 in ia[]. "<<endl;

        system("pause");

        return0;

}

 

 

 

13.重写程序,查找元素的值,并返回指向找到的元素的迭代器。确保程序在要寻找的元素不存在时也能正确工作。

#include"stdafx.h"

#include<iostream>

#include<vector>

#include<cassert>

usingnamespace std;

 

typedefvector<int>::iterator iter;

itergetTheIterOfX( iterfirst, iter last, int x )

{

        assert( first <=last);

 

        for ( iterit = first; it != last; ++it )

        {

                  if( *it ==x )

                  {

                           return it;

                  }

        }

}

 

int_tmain(int argc, _TCHAR* argv[])

{

        int ia[] = { 0, 1, 2, 3, 4, 5 };

        vector<int>ivec( ia, ia+5 );

        

        iter it= getTheIterOfX(ivec.begin(), ivec.end(), 3 );

        if ( (*it) )

        {

                  cout<< " We got x in ia[], its valueis:\t" << *it <<endl;

        }

 

        system("pause");

        return0;

}

 

 

14.使用迭代器编写程序,从标准输入设备读入若干string对象,并将它们存储在一个vector对象中,然后输出该vector对象中的所有元素。

//11.15_9.14_vector_string.cpp :定义控制台应用程序的入口点。

//

#include"stdafx.h"

#include<iostream>

#include<vector>

#include<string>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        cout<< "\tInput some strings ( ctrl+z to end):" <<endl;

        vector<string>strVec;

        stringstr;

        while (cin >>str)

        {

                  strVec.push_back(str );

        }

 

        cout<< " All the member of thevector<string> strVec are:\n";

        for ( vector<string>::iteratorit = strVec.begin();it != strVec.end(); ++it )

        {

                  cout<< *it <<endl;

        }

 

        system("pause");

        return0;

}

 

15.list容器类型重写习题9.14得到的程序,列出改变了容器类型后要做的修改。

//11.15_9.15_list_string.cpp :定义控制台应用程序的入口点。

//

#include"stdafx.h"

#include<iostream>

#include<list>

#include<string>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        cout<< "\tInput some strings ( ctrl+z to end):" <<endl;

        list<string>strLst;

        stringstr;

        while (cin >>str)

        {

                  strLst.push_back(str );

        }

 

        cout<< " All the member of theList<string> strLst are:\n";

        for ( list<string>::iteratorit = strLst.begin();it != strLst.end(); ++it )

        {

                  cout<< *it <<endl;

        }

 

        system("pause");

        return0;

}

 

16.int型的vector容器应该使用什么类型的索引?

使用vector<int>::size_type的索引。

 

17.读取存放string对象的list容器时,应该使用什么类型?

使用list<string>::iterator it,进行索引,然后解引用 *it.

或者使用list<string>::const_iterator类型的迭代器。

若想实现逆序读取,则可使用

 list<string>::reverse_iterator list<string>::const_reverse_iterator迭代器。

 

 

 

18.编写程序将int型的list容器的所有元素复制到两个deque容器中。list容器的元素如果为偶数,则复制到一个deque容器中;如果为奇数,则复制到另一个deque容器里。

//11.15_9.18_list_to_deque.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<list>

#include<deque>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        cout<< "\tInput some int numbers ( ctrl+z toend ):" <<endl;

        list<int>iLst;

        int iVal;

        while (cin >>iVal)

        {

                  iLst.push_back(iVal );

        }

 

        deque<int>iOddDeque, iEvenDeque;

 

        for ( list<int>::iteratorit = iLst.begin();it != iLst.end(); ++it )

        {

                  if( *it % 2 == 0 )

                  {

                           iEvenDeque.push_back(*it );

                  }

                  elseif ( *it % 2== 1 )

                  {

                           iOddDeque.push_back(*it );

                  }

        }

        cout<< " All the numbers inputed, the oddnumbers are:" <<endl;

        for ( deque<int>::iteratorit = iOddDeque.begin();it != iOddDeque.end(); ++it )

        {

                  cout<< *it <<"  ";

        }

        cout<< "\n All the numbers inputed, the evennumbers are:" <<endl;

        for ( deque<int>::iteratorit = iEvenDeque.begin();it !=iEvenDeque.end(); ++it )

        {

                  cout<< *it <<"  ";

        }

 

        system("pause");

        return0;

}

 

19.假设iv是一个int型的vector容器,下列程序存在什么错误?如何改正之。

vector<int>::iteratormid = iv.begin() + iv.end()/2;

while( vector<int>::iterator iter != mid )

        if ( iter == some_val )

                  it.insert ( iter, 2 *some_val );

1)当执行it.insert操作之后,迭代器 mid 就失效了,是因为 iv.end()失效了。

2)迭代器iter没有初始化;

3if语句中错误,因为 if ( *iter == some_val )

可改为:

vector<int>::iterator iter = iv.begin();

while ( iter != iv.begin() + iv.end() / 2 )

{

        if ( *iter ==some_val )

        {

                  it.insert (iter, 2 * some_val );

                  iter += 2; //important

        }

        else 

                  ++iter;

}

 

20.编写程序判断一个vector<int>容器所包含的元素是否与一个list<int>容器的完全相同。

//11.15_9.20_compare_list_and_vector.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<list>

#include<vector>

usingnamespace std;

 

 

int_tmain(int argc, _TCHAR* argv[])

{

        cout<< "\tInput some int numbers to a list (999 to end ):" <<endl;

        list<int>iLst;

        int iVal;

        while (cin >>iVal)

        {

                  if( iVal == 999 )break;

                  iLst.push_back(iVal );

        }

 

        cout << "\nInputsome int numbers to a vector( 888 to end ):" << endl;

        vector<int>iVec;

        int i;

        while (cin >>i)

        {

                  if( i == 888 )break;

                  iVec.push_back(i );

        }

 

        bool bSame =true;

 

        if ( iLst.size() !=iVec.size() )

        {

                  bSame= false;

        }

        else

        {

                  list<int>::iteratorit_l = iLst.begin();

                  vector<int>::iteratorit_v = iVec.begin();

                  while( it_l !=iLst.end() )

                  {

                           if ( *it_l != *it_v )

                           {

                                    bSame = false;

                                    break;

                           }

                           it_l++;

                           it_v++;

                  }

        }

        

        if ( bSame )

        {

                  cout<< " They have all the same elements foriVec and iLst. " <<endl;

        }

        else

                  cout<< " They are not same of iVec and iLst." <<endl;

        

 

        

 

        system("pause");

        return0;

}

 

21.假设c1c2都是容器,下列用法给c1c2的元素类型带来什么约束?

if( c1 < c2 )

(如果有的话)对c1c2的约束又是什么?

c1c2的元素类型的约束为:类型必须相同,且必须都支持 < 操作符。

 

22.已知容器vec存放了25个元素,那么vec.resize(100)操作实现了什么功能?若再做操作vec.resize(10),实现的功能又是什么?

vec的大小改为100,且把新添加的元素值初始化。

又将vec的后90个元素删除,将vec的大小改为10

 

23.使用只带有一个长度参数的resize操作对元素类型有什么要求?

对容器里存放的数据类型必须支持值默认初始化。

 

24.编写程序获取vector容器的第一个元素。分别使用下标操作符,front函数以及begin函数实现该功能,并提供空的vector容器测试你的程序。

//11.15_9.24_vector_getTheFirstElement.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<vector>

usingnamespace std;

 

 

int_tmain(int argc, _TCHAR* argv[])

{

        cout<< "\tInput some int numbers to a vector( ctrl+z to end ):" <<endl;

        vector<int>iVec;

        int i;

        while (cin >>i)

        {

                  iVec.push_back(i );

        }

 

        if ( !iVec.empty() )

        {

                  cout<< " The first element of the vectoris:";

                  cout<<"\n\t==>> Using front():\t"<<iVec.front();

                  cout<<"\n\t==>> Using begin():\t"<< *iVec.begin();

                  cout<<"\n\t==>> Using iVec[0]:\t"<<iVec[0];

                  cout<<"\n\t==>> UsingiVec.at(0):\t" <<iVec.at(0) << endl;

        }

        

 

        system("pause");

        return0;

}

 

 

当用空的vector时,会产生运行时错误,或者抛出异常(使用 vec.at(0) ).

 

25.需要删除一段元素时,如果val1val2相等,那么程序会发生什么事情?如果val1val2中的一个不存在,或两个都不存在,程序又会怎么样?

相等,则不会删除任何元素;

若有一个不存在,则会发生运行时错误;

 

 

 

26.假设有如下ia的定义,将ia复制到一个vector容器和一个list容器中。使用单个迭代器参数版本的erase函数将list容器中的奇数值元素删除掉,然后将vector容器中的偶数值元素删除掉。

intia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };

//11.15_9.26_ia_To_vector_and_list_Erase.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<list>

#include<vector>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };

        vector<int>iVec( ia, ia+11 );

        list<int>iLst( ia, ia+11 );

 

        cout<< " Before erase, the elements of iVec are:" <<endl;

        for ( vector<int>::iteratorit = iVec.begin();it != iVec.end(); ++it )

                  cout<< *it <<"";

        cout<< "\n Before erase, the elements of iLst are:" <<endl;

        for ( list<int>::iteratorit = iLst.begin();it != iLst.end(); ++it )

                  cout<< *it <<"";

 

        // 2 erase

        for ( vector<int>::iteratoriter = iVec.begin();iter != iVec.end(); ++iter )

        {

                  if( *iter % 2 == 0 )

                  {

                           iter = iVec.erase(iter );

                  }

        }

        for ( list<int>::iteratorLit = iLst.begin();Lit != iLst.end(); ++Lit )

        {

                  if( *Lit % 2 == 1 )

                  {

                           Lit = iLst.erase(Lit );

                           --Lit;

                  }

        }

 

 

        // show

        cout<< "\n After erase, the elements of iVec are:" <<endl;

        for ( vector<int>::iteratorit = iVec.begin();it != iVec.end(); ++it )

                  cout<< *it <<"";

        cout<< "\n After erase, the elements of iLst are:" <<endl;

        for ( list<int>::iteratorit = iLst.begin();it != iLst.end(); ++it )

                  cout<< *it <<"";

        cout<< endl;

 

        system("pause");

        return0;

}

 

 

27.编写程序处理一个string类型的list容器。在该容器中寻找一个特殊值,如果找到,则将它删除掉。用deque容器重写上述程序。

//11.15_9.27_StringList_Find_Earse.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<list>

#include<string>

#include<algorithm>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        stringstrSerVal("hit");

        stringstrArr[] = {"Hello","world","hit"};

        list<string>strLst( strArr,strArr + 3);

        list<string>::iteratorLit =find( strLst.begin(),strLst.end(), strSerVal );

        if ( Lit !=strLst.end() )

        {

                  cout<< " we find 'hit' in the list, thenerase it." <<endl;

                  strLst.erase(Lit );

        }

        

        system("pause");

        return0;

}

deque重写以上程序:

      stringstrSerVal("hit");

        stringstrArr[] = {"Hello","world","hit"};

      deque<string>strDeq( strArr,strArr + 3 );

        deque<string>::iteratorDit =find( strDeq.begin(),strDeq.end(), strSerVal );

        if ( Dit !=strDeq.end() )

        {

                  cout<< "\n\n we find 'hit' in the deque, thenerase it." <<endl;

                  strDeq.erase(Dit );

        }

 

 

28.编写一个程序将一个list容器的所有元素赋值给一个vector容器,其中list容器中存储的是指向C风格字符串的char*指针,而vector容器的元素则是string类型。

//11.15_9.28_assignListToVector.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<list>

#include<vector>

#include<string>

usingnamespace std;

                                                                                    

int_tmain(int argc, _TCHAR* argv[])

{

        char *c_arr[] = {"one","two", "three"};

        list<char*>pLst;

        pLst.assign(c_arr, c_arr+3 );

        cout<< "\tAll the members in thelist<char*> pLst are:\n";

        for ( list<char*>::iteratorit = pLst.begin();it != pLst.end(); ++it )

        {

                  cout<< *it <<"";

        }

 

        vector<string>strVec;

        strVec.assign(pLst.begin(), pLst.end() );

        cout<< "\n\tAfter assignment from list, thevector<string> strVec are:\n";

        for ( vector<string>::iteratorit = strVec.begin();it != strVec.end(); ++it )

        {

                  cout<< *it <<"";

        }

        cout<< endl;

 

        system("pause");

        return0;

}

 

29.解释vector的容量和长度之间的区别。为什么在连续存储元素的容器中需要支持“容量”的概念?而非连续的容器,如list,则不需要。

容量capacity,是指容器在必须分配新的存储空间之前可以存储的元素的总数。而长度是指容器当前拥有的元素的个数。

对于连续存储的容器来说,容器中的元素时连续存储的,当往容器中添加一个元素时,如果容器中已经没有空间容纳新的元素,则为了保持元素的连续存储,必须重新分配存储空间,用来存放原来的元素以及新添加的元素:首先将存放在旧存储空间中的元素复制到新的存储空间里,然后插入新的元素,最后撤销旧的存储空间。如果在每次添加新元素时,都要这样分配和撤销内存空间,其性能将会慢得让人无法接受。为了提高性能,连续存储元素的容器实际分配的容量要比当前所需的空间多一些,预留了一些额外的存储区,用于存放新添加的元素,使得不必为每个新的元素重新分配容器。所以,在连续存储元素的容器中需要支持“容量”的概念。

而对于不连续存储的容器,不存在这样的内存分配问题。例如当在list容器中添加一个元素,标准库只需创建一个新元素,然后将该新元素连接到已经存在的链表中,不需要重新分配存储空间,也不必复制任何已存在的元素。所以这类容器不需要支持“容量”的概念。

 

30.编写程序研究标准库为vector对象提供的内存分配策略。

//11.15_9.30_vector_capacity_and_reserve.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<vector>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        vector<int>ivec;

        cout<< " ivec.size() : " <<ivec.size()<<endl

                  << " ivec.capacity() : " << ivec.capacity()<< endl;

        

        // add newelements:

        for ( size_tix = 1; ix != 11; ++ix )

        {

                  ivec.push_back(ix );

                  cout<< " ivec.size() : " <<ivec.size()<<endl

                           << " ivec.capacity() : " << ivec.capacity()<< endl;

        }

 

        // use up thecurrent capacity of the vector  

        while (ivec.size()!=ivec.capacity())

        {

                  ivec.push_back( 0 );

        }

 

        // add onemore

        ivec.push_back(0);

        // show thecurrent capacity of the vector

        cout<< " ivec.size() : " <<ivec.size()<<endl

                  << " ivec.capacity() : " << ivec.capacity()<< endl;

 

        // resize thecapacity of the vector

        ivec.reserve( 100 );

        // show thecurrent capacity of the vector

        cout<< " ivec.size() : " <<ivec.size()<<endl

                  << " ivec.capacity() : " << ivec.capacity()<< endl;

 

        // use up thecurrent capacity of the vector

        while (ivec.size()!=ivec.capacity())

        {

                  ivec.push_back( 0 );

        }

 

        // add onemore

        ivec.push_back(0);

        // show thecurrent capacity of the vector

        cout<< " ivec.size() : " <<ivec.size()<<endl

                  << " ivec.capacity() : " << ivec.capacity()<< endl;

 

 

        system("pause");

        return0;

}

 

 

31.容器的容量可以比其长度小吗?在初始时或插入元素后,容量是否恰好等于所需要的长度?为什么?

不能。

在初始时,或插入元素后,容量不会恰好等于所需要的长度,一般会大于长度,因为系统会根据一定的分配策略预留一些额外的存储空间以备容器的增长,从而避免了重新分配内存、复制元素、释放内存等操作,提高性能。

 

32.解释下面程序实现的功能:

vector<string>svec;

svec.reserve(1024 );

stringtext_word;

while( cin >> text_word )

        svec.push_back( text_word );

svec.resize(svec.size() + svec.size()/2 );

如果该程序读入了256个单词,在调整大小后,该容器的容量可能是多少?如果读入512,或1000,或1048个单词呢?

功能:将svecsize设定为1024,然后从标准输入设备读入一系列单词,最后将该vector对象的大小调整为所读入单词个数的1.5倍。

当读入256512时,容器的容量不变,仍为1024,因为容器大小没有超出已分配内存容量。调整大小只改变容器中有效元素的个数,不会改变容量。

当读入1000时,最后调整容量时,需要1500个元素的存储空间,超过了已分配的容量1024,所以可能重新分配为1536的容量。

当读入1048时,在读入1025个时,容器的容量可能会增长为1536,最后输入完1048个单词后,在调整大小后,需要1572个元素的存储空间,超过了已分配的1536,因此再次重分配,容量再增长0.5倍,变为2304 

 

33.对于下列程序任务,采用哪种容器实现最合适?解释选择的理由。如果无法说明采用某种容器比另一种容器更好的原因,请解释为什么?

(a)从一个文件中读入未知数目的单词,以生成英文句子。

(b)读入固定数目的单词,在输入时将它们按字母顺序插入到容器中,下一章将介绍何时处理此类问题的关联容器。

(c)读入未知数目的单词,总是在容器尾部插入新单词,从容器首部删除下一个值。

(d)从一个文件中读入未知数目的整数。对这些整数排序,然后把它们输出到标准输出设备。

(a)以给确定的顺序随机处理这些单词,采用vector最合适。

(b) list何时,因为需要在容器的任意位置插入元素。

(c) deque合适,因为总是在尾部和首部进行插入和删除的操作。

(d)如果一边输入一边排序,则采用list合适,如果先读入所有的整数,然后排序,则用vector合适,因为进行排序最好有随机访问的能力。

 

 

34.使用迭代器将string对象中的字符都改为大写字母。

//11.15_9.34_string_toupper.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<string>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        stringstr;

        cout<< " Input a string:\t";

        cin>> str;

        cout<< "\n Original str:\t "<<str << endl;

        for ( string::iteratorit = str.begin();it != str.end(); ++it )

        {

                  *it= toupper( *it);

        }

 

        cout<< "\n Toupper, the str:\t "<<str << endl;

        system("pause");

        return0;

}

 

 

35.使用迭代器寻找和删除string对象中所有的大写字符。

#include"stdafx.h"

#include<iostream>

#include<string>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        stringstr;

        cout<< " Input a string:\t";

        cin>> str;

        cout<< "\n Original str:\t "<<str << endl;

        for ( string::iteratorit = str.begin();it != str.end(); ++it )

        {

                  if( isupper( *it) )

                  {

                           str.erase(it );

                           it--;

                  }

        }

 

        cout<< "\n After deal, the str:\t "<<str << endl;

        system("pause");

        return0;

}

 

36.编写程序用vector<char>容器初始化string对象。

//11.15_9.36_vectorCharToString.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<string>

#include<vector>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        vector<char>cVec;

        char cVal;

        cout<< " Input some letters tovector<char> cVec :\t";

        while (cin >>cVal)

                  cVec.push_back(cVal );

 

        stringstr(cVec.begin(), cVec.end() );

        cout<< "\n After deal, the str:\t "<<str << endl;

        system("pause");

        return0;

}

 

37.假设希望一次读取一个字符并写入string对象,而且已知需要读入至少100个字符,考虑应该如何提高程序的性能?

string对象中的字符时连续存储的,为了提高性能,事先应该将对象的容量指定为至少100个字符的容量,以避免多次进行内存的重新分配。可使用 reserve函数实现。

 

38.已知有如下string对象:

“ab2c3d7R4E6”

编写程序寻找该字符串中所有的数字字符,然后再寻找所有的字母字符。以两种版本编写该程序:第一个版本使用find_first_of函数,而第二个版本则使用find_first_not_of函数。

第一个版本:

//11.15_9.38_find_fist_of.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<string>

 

usingnamespace std;

 

 

int_tmain(int argc, _TCHAR* argv[])

{

  string strSearchVal("ab2c4d7R4E6");

  string numerics("0123456789");

  string::size_typepos = 0;

  // find num

  while ( ( pos =strSearchVal.find_first_of(numerics,pos )) !=string::npos )

  {

          cout << "\nFound number at index:  "<< pos << "element is:  " <<strSearchVal[pos]<<endl;

          ++pos;

  }

 

  // find letters

  string letters("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");

  pos = 0;

  while ( ( pos =strSearchVal.find_first_of(letters,pos )) !=string::npos )

  {

          cout << "\nWe found letter at index:  "<< pos

                     << "element is: " <<strSearchVal[pos] <<endl;

          ++pos;

  }

        system("pause");

        return0;

}

第二个版本:

#include"stdafx.h"

#include<iostream>

#include<string>

 

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        stringstrSearchVal("ab2c4d7R4E6");

        stringnumerics("0123456789");

        stringletters("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");

        string::size_typepos = 0;

        // find num

        while (( pos =strSearchVal.find_first_not_of(letters,pos )) !=string::npos )

        {

                  cout<< "\n Found number at index: " << pos << "element is:  " << strSearchVal[pos]<<endl;

                  ++pos;

        }

 

        // findletters

        

        pos =0;

        while (( pos =strSearchVal.find_first_not_of(numerics,pos )) !=string::npos )

        {

                  cout<< "\n We found letter at index: " << pos

                           << " element is: " << strSearchVal[pos]<< endl;

                  ++pos;

        }

        system("pause");

        return0;

}

 

 

39.已知有如下string对象:

stringline1 = “ We were her pride of 10 she named us:“;

stringline2 = “Benjamin, Phoenix, the Prodigal“;

stringline3 = “and perspicacious pacific Suzanne“;

 

stringsentence = line1 + ‘ ‘ + line2 + ‘ ‘ + line3;

编写程序计算sentence中有多少个单词,并指出其中最长和最短单词。如果有多个最长或最短单词,则将它们全部输出。

 

//11.15_9.39_find_howManyWords.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<vector>

#include<string>

 

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        stringseparators(":\t,\v\r\n\f");

        // find howmany words

        stringline1 ="Wewere her pride of 10 she named us:";

        stringline2 ="Benjamin,Phoenix, the Prodigal";

        stringline3 ="andperspicacious pacific Suzanne";

        stringsentence =line1+ ' ' + line2+ ' ' + line3;

        stringword;

        string::size_typemaxLen, minLen,wordLen;

        vector<string>longestWords,shortestWords;

 

        cout<< "\n The sentence is :\n"<<sentence << endl;

        string::size_typestartPos= 0, endPos = 0;

        size_tcnt = 0;

        while (( startPos =sentence.find_first_not_of(separators,endPos )) !=string::npos )

        {

                  ++cnt;

                  endPos= sentence.find_first_of(separators,startPos);

                  if( endPos ==string::npos )

                           wordLen = sentence.size() -startPos;

                  else

                           wordLen = endPos -startPos;

        

                  word.assign(sentence.begin() +startPos,sentence.begin()+startPos + wordLen);

                  startPos= sentence.find_first_not_of(separators,endPos);

                  if( cnt == 1 )

                  {

                           maxLen = minLen =wordLen;

                           longestWords.push_back(word );

                           shortestWords.push_back(word );

                  }

                  else

                  {

                           if ( wordLen >maxLen )

                           {

                                    maxLen = wordLen;

                                    longestWords.clear();

                                    longestWords.push_back(word );

                           }

                           else if ( wordLen == maxLen )

                           {

                                    longestWords.push_back(word );

                           }

 

                           if ( wordLen <minLen )

                           {

                                    minLen = wordLen;

                                    shortestWords.clear();

                                    shortestWords.push_back(word );

                           }

                           else if ( wordLen == minLen )

                           {

                                    shortestWords.push_back(word);

                           }

                  }

        }

 

        // coutnumber of words

        cout<< "\n\t There are " <<cnt <<"words in the sentence." << endl;

        vector<string>::iteratoriter;

        // out thelongest word

        cout<< "\n\t longest word :"<<endl;

        iter =longestWords.begin();

        while (iter !=longestWords.end() )

        {

                  cout<< *iter++ <<endl;

        }

 

        // out theshortest word

        cout<< "\n\t shortest word :"<<endl;

        iter =shortestWords.begin();

        while (iter !=shortestWords.end() )

        {

                  cout<< *iter++ <<endl;

        }

 

 

        system("pause");

        return0;

}

 

 

 

40.编写程序接受下列两个string对象:

stringq1( “ When lilacs last in the dooryard bloom’d”);

stringq2(“The child is father of the man”);

然后使用assignappend操作,创建string对象:

stringsentence(“The child is in the dooryard”);

 

//11.15_9.40_compare_and_append_assign.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<string>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        stringq1("Whenlilacs last in the dooryard bloom’d" );

        stringq2("The childis father of the man" );

        // compare q1and q2

        if ( q1.compare(q2 ) > 0 )

                  cout<< "\n\t==>> q1 > q2. "<<endl;

        else if ( q1.compare( q2 ) <0 )

                  cout<< "\n\t==>> q1 < q2. "<<endl;

        else if ( q1.compare( q2 ) == 0)

        {

                  cout<< "\n\t==>> q1 == q2. "<<endl;

        }

        // createsentence: string sentence(“The child is in the dooryard”);

        stringsentence;

        sentence.assign(q2.begin(), q2.begin() + 12 );

        sentence.append(q1, 16,16);

        cout<< "\n\tThen the sentence is :\n\t"<<sentence << endl;

 

        system("pause");

        return0;

}

 

 

 

41.已知有如下string对象:

stringgeneric1(“Dear Ms Daisy:”);

stringgeneric2(“MrsMsMissPeople”);

编写程序实现下面函数:

stringgreet( string form, string lastname, string title, string::size_type pos, intlength );

该函数使用replace操作实现以下功能:对于字符串form,将其中的Daisy替换为lastname,将其中的Ms替换为字符串generic2中从pos下标开始的length个字符。

例如,下面的语句:

stringlastName( “ AnnaP” );

stringsalute = greet( generic1, lastName, generic2, 5, 4 );

将返回字符串:

DearMiss AnnaP:

//11.15_9.41_replace.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<string>

usingnamespace std;

 

stringgreet( string form, string lastname,string title, string::size_type pos, int length )

{

        string::size_typepos_Daisy,pos_Ms;

        // replace"Dasiy" to lastname("AnnnaP")

        while (( pos_Daisy =form.find( "Daisy")) != string::npos)

                   form.replace(pos_Daisy,lastname.size(),lastname );

 

        // replace"Ms" to "Miss"

        while (( pos_Ms =form.find( "Ms")) != string::npos)

                   form.replace(pos_Ms, 2,title,pos, length );

 

        return form;

}

 

int_tmain(int argc, _TCHAR* argv[])

{

        stringgeneric1("DearMs Daisy:");

        stringgeneric2("MrsMsMissPeople");

 

        stringlastName("AnnaP");

        stringsalute =greet(generic1,lastName,generic2, 5, 4 );

 

        cout<< salute <<endl;

        system("pause");

        return0;

}

 

42.编写程序读入一系列单词,并将它们存储在stack对象中。

 

//11.15_9.42_stack_deque.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<string>

#include<deque>

#include<stack>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        stack<string>strStack;

        cout<< "\tInput some words ( ctrl+z to end):\n\t";

        stringword;

        while (cin >>word)

                  strStack.push(word );

 

        // show outthe elements of the stack

        cout<< "\nThe elements of the stackare:" <<endl;

        while (! strStack.empty())

        {

                  cout<< strStack.top()<<endl;

                  strStack.pop();

        }

 

        system("pause");

        return0;

}

 

 

43.使用stack对象处理带圆括号的表达式。遇到左圆括号时,将其标记下来。然后遇到右圆括号时,弹出stack对象中这两边括号之间的相关元素(包括左圆括号)。接着在stack对象中压入一个值,用以表明这个用一对圆括号括起来的表达式已经被替换。

 

//11.15_9.43_stack_application.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

//11.15_9.42_stack_deque.cpp :定义控制台应用程序的入口点。

//

 

#include"stdafx.h"

#include<iostream>

#include<string>

#include<stack>

#include<deque>

usingnamespace std;

 

int_tmain(int argc, _TCHAR* argv[])

{

        stack<char>sExp;

        stringstrExp;

        cout<< " Input a expression: ";

        cin>> strExp;

 

        // deal thesExp

        string::iteratorit = strExp.begin();

        while (it !=strExp.end() )

        {

                  if( *it !=')')

                           sExp.push( *it );

                  else

                  {

                           while ( ( sExp.top() !='(' )&& !sExp.empty())

                           {

                                    sExp.pop();

                           }

                  }

 

                  if( sExp.empty())

                           cout << " It'snot matched. " <<endl;

                  else

                  {

                           sExp.pop();

                           sExp.push('@');

                  }

 

                  ++it;

        }

 

        // show outthe elements of the stack

        cout<< "\nThe elements of the stackare:" <<endl;

        while (! sExp.empty())

        {

                  cout<< sExp.top()<<endl;

                  sExp.pop();

        }

 

        system("pause");

        return0;

}

0 0
原创粉丝点击