C++Primer第五版 第九章习题答案(41~50)

时间:2023-02-13 20:22:24

41:知识点1:标准库string定义了大量的特殊操作,并且各种操作皆可重载,因此数量巨大,可以适当进行浏览,当具体需要某种形式时,再进行翻阅查找

知识点2:string的额外构造方法:利用数组、string进行构造

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

int main(int argc, char**argv)
{
vector<char> vec1(6,'a');
string _string(vec1.begin(),vec1.end());//此时不是本节所介绍的特殊方法
cout<<_string<<endl;

return 0;
}


42:利用reverse()操作预留足够的内存,这样就不用在过程中进行修改内存的操作。


43:知识点:string除了前面介绍的标准顺序容器的erase()和insert()之外还有其特殊的insert()和erase()版本

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

void func(string &s, string &oldVal, string &newVal)
{
int _size = oldVal.size();
string::iterator it1 = s.begin();
string::iterator it2 = newVal.begin();
string::iterator it3 = newVal.end();

for (it1; it1 <= (s.end()-oldVal.size()+1); ++it1)
{
//pos可以由两个迭代器相减得到,返回截取到的string
if((s.substr(it1-s.begin(),_size) == oldVal))//substr()的作用就是截取string中的一段
{
it1 = s.erase(it1,it1+_size);//返回的是最后一个被删除的元素之后的位置
it1 = s.insert(it1, it2, it3);//VS2010运行出错,但是未找到原因何在,本质上说应该是没有错误的
advance(it1,_size);//向前一定大小
}
}
}

int main(int argc, char**argv)
{
string s = "abcdefg";
string oldval = "bc";
string newval = "asas";
func(s,oldval,newval);
cout<<s<<endl;
return 0;
}

改进:

#include<iostream>  
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

void func(string &s, string &oldVal, string &newVal)
{
int _size = oldVal.size();
string::iterator it1 = s.begin();
string::iterator it2 = newVal.begin();
string::iterator it3 = newVal.end();

for (it1; it1 <= (s.end()-oldVal.size()+1); ++it1)
{
//pos可以由两个迭代器相减得到,返回截取到的string
if((s.substr(it1-s.begin(),_size) == oldVal))//substr()的作用就是截取string中的一段
{
it1 = s.erase(it1,it1+_size);//返回的是最后一个被删除的元素之后的位置
s.insert(it1, it2,it3);//原因在于insert()函数返回了指向第一个插入字符的迭代器,而我将其直接赋值给it1,从const转为非const,类型不同,产生错误
advance(it1,_size);//向前_size大小,目的是为了让it1仍然指向当前字符串的首位置,因为前面进行了++it1
}
}
}

int main(int argc, char**argv)
{
string s = "abcdefg";
string oldval = "bc";
string newval = "asas";
func(s,oldval,newval);
cout<<s<<endl;
system("pause");
return 0;
}



44:知识点:这些操作函数的使用只要加以练习,可以达到知道有这样的操作存在的状态,就应该基本满足学习结果。

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

void func(string &s, string &oldVal, string &newVal)
{
int _size = oldVal.size();
string::iterator it1 = s.begin();

for (it1; it1 <= (s.end()-oldVal.size()+1); ++it1)
{
//pos可以由两个迭代器相减得到,返回截取到的string
if((s.substr(it1-s.begin(),_size) == oldVal))//substr()的作用就是截去string中的一段
{
s.replace(it1-s.begin(),_size,newVal);//返回的是一个指向s的引用
}
}
}

int main(int argc, char**argv)
{
string s = "abcdefg";
string oldval = "bc";
string newval = "asas";
func(s,oldval,newval);
cout<<s<<endl;
return 0;
}


45:知识点:append()直接在字符串之后加上相关的参数

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

void func(string &name, string &frontVal, string &backVal)
{
string::iterator it1 = name.begin();
name.append(backVal);
name.insert(it1,frontVal.begin(),frontVal.end());
}

int main(int argc, char**argv)
{
string s = "Xia";
string frontval = "Mr.";
string newval = " III";
func(s,frontval,newval);
cout<<s<<endl;
return 0;
}

46:知识点:理解其操作函数的各式重载

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

void func(string &name, string &frontVal, string &backVal)
{
string::iterator it1 = name.begin();

name.insert(it1,frontVal.begin(),frontVal.end());

name.insert(name.end(),backVal.begin(),backVal.end());//不要保存end迭代器
name.insert(name.size(),backVal);//同样作用,重载可用
}

int main(int argc, char**argv)
{
string s = "Xia";
string frontval = "Mr.";
string newval = " III";
func(s,frontval,newval);
cout<<s<<endl;
return 0;
}


47:知识点:string中的搜索函数,需要注意的是函数的返回值:string::size_type类型,找到时返回第一个匹配的下标位置,找不到时返回npos.,注意皆为unsigned类型

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

int main(int argc, char**argv)
{
string s = "ab2c3d7R4E6";
string number = "0123456789";
unsigned pos = 0;
//循环中我犯了一个错误,没有将pos=左右加括号,导致无线循环
while ((pos = s.find_first_of(number,pos)) != string::npos)//注意有两个参数,从pos开始查找
{
cout<<"在第"<<pos+1<<"个位置找到数字"<<s[pos]<<endl;
++pos;
}
pos = 0;//重新置零
while ((pos = s.find_first_not_of(number,pos)) != string::npos)//注意有两个参数,从pos开始查找
{
cout<<"在第"<<pos+1<<"个位置找到英文字母"<<s[pos]<<endl;
++pos;
}

return 0;
}

C++Primer第五版 第九章习题答案(41~50)

48:string::npos,什么也找不到


49:先写出26个英文字母判断一下acenmorsuvwxz为符合要求的字母

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;

int main(int argc, char**argv)
{
string s = "acenmorsuvwxz";
//ifstream infile(argv[1]);
ifstream infile("1.txt");
string str;
infile>>str;//单词文件读入
cout<<"原字符串为:"<<str<<endl;

unsigned pos1 = 0;
unsigned pos2 = 0;
unsigned _legenth = 0;
unsigned pos3 = 0;

while((pos1 = str.find_first_of(s,pos1)) != string::npos)//找到第一个不出头字符
{
pos2 = pos1;
if ((pos2 = str.find_first_not_of(s,pos2)) != string::npos)//从第一个不出头字符开始找到第一个出头字符
{
if (pos2 - pos1 >= _legenth)//找出最大长度并记录此区间的首位置
{
_legenth = pos2 - pos1;
pos3 = pos1;
}
}
++pos1;
}
string _string = str.substr(pos3,_legenth);
cout<<"最长不出头串:"<<_string<<endl;
return 0;
}

50:知识点:数值数据可以与标准库string之间进行数值转换

#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<forward_list>
using namespace std;


int main(int argc, char**argv)
{
vector<string> _string(5,"10");
int sum1 = 0;
double sum2 = 0.0;
for (int i = 0; i < _string.size(); ++i)
{
sum1 += stoi(_string[i]);
sum2 += stod(_string[i]);
cout<<stod(_string[i])<<endl;
}
cout<<"int和为:"<<sum1<<endl;
cout<<"double和为:"<<sum2<<endl;

return 0;
}