C++primer(第五版)9.5.1节,9.5.2节,9.5.3节,9.5.5节,9.6节练习答案

练习9.41:编写程序,从一个vector<char>初始化一个string。

解答:

#include<iostream>
#include<string>
#include<vector>

using std::vector;using std::string;using std::cout;using std::endl;

int main()
{
	vector<char> cvec{'h','i'};
	string s(cvec.begin(),cvec.end());
	cout<<s<<endl;

	return 0;
}


练习9.42:假定你希望每次读取一个字符存入string中,而且知道最少需要读取100个字符,应该如何提高程序的性能?

解答:

用成员函数reserve去为string预先分配足够大的存储空间。


练习9.43:编写一个函数,接受三个string参数s、oldVal和newVal。使用迭代器及insert和erase函数将s中所有oldVal替换为newVal。测试你的程序,用它替换通用的简写形式,如,将"tho"替换为”though“,将"thru"替换为"through"。

解答:

#include<iostream>
#include<string>

using std::string;using std::cout;using std::endl;

void func(string& s, const string& oldVal,const string& newVal)
{
	for(string::size_type i=0; i!=s.size(); ++i)	
	{
		if(s.substr(i,oldVal.size()) == oldVal)
		{
			s.erase(i,oldVal.size());
			s.insert(i,newVal);
		}
	}
}

int main()
{
	string str{"drive straight thru is a foolish, tho courageous act."};
	func(str,"thru","through");
	func(str,"tho","though");
	cout<<str<<endl;

	return 0;
}


练习9.44:重写上一题的函数,这次使用一个下标和replace。

解答:

#include<iostream>
#include<string>

using std::string;using std::cout;using std::endl;

void func(string& s, const string& oldVal,const string& newVal)
{
	for(string::size_type i=0; i!=s.size(); ++i)	
	{
		if(s.substr(i,oldVal.size()) == oldVal)
		{
			s.replace(i,oldVal.size(),newVal);
		}
	}
}

int main()
{
	string str{"drive straight thru is a foolish, tho courageous act."};
	func(str,"thru","through");
	func(str,"tho","though");
	cout<<str<<endl;

	return 0;
}


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

解答:

#include<iostream>
#include<string>

using std::string;using std::cout;using std::endl;

string func(string& name, const string& pre,const string& su)
{
	string ret(name);
	ret.insert(0,pre);
	ret.append(su);

	return ret;
}

int main()
{
	string name{"mango"};
	cout<<func(name,"Mr.","Jr.")<<endl;

	return 0;
}


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

解答:

#include<iostream>
#include<string>

using std::string;using std::cout;using std::endl;

string func(string& name, const string& pre,const string& su)
{
	string ret(name);
	ret.insert(0,pre);
	ret.insert(ret.size(),su);

	return ret;
}

int main()
{
	string name{"mango"};
	cout<<func(name,"Mr.","Jr.")<<endl;

	return 0;
}

练习9.47:编写程序,首先查找string"ab2c3d7R4E6"中的每个数字字符,然后查找其中每个字母字符。编写两个版本的程序,第一个要使用find_first_of,第二个要使用find_first_not_of。

解答:

//find_first_of
#include<iostream>
#include<string>

using std::string;using std::cout;using std::endl;

int main()
{
	string numbers{"0123456789"};
	string alphabet{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
	string str{"ab2c3d7R4E6"};

	cout<<"numberic characters:"<<endl;
	for(string::size_type i=0;  (i = str.find_first_of(numbers,i)) != string::npos; ++i)
		cout<<str[i]<<" ";
	cout<<endl;

	cout<<"alphabetic characters:"<<endl;
	for(string::size_type i=0; (i = str.find_first_of(alphabet,i)) != string::npos; ++i)
		cout<<str[i]<<" ";
	cout<<endl;
		
	return 0;
}


//find_first_not_of
#include<iostream>
#include<string>

using std::string;using std::cout;using std::endl;

int main()
{
	string numbers{"0123456789"};
	string alphabet{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"};
	string str{"ab2c3d7R4E6"};

	cout<<"numberic characters:"<<endl;
	for(string::size_type i=0;  (i = str.find_first_not_of(alphabet,i)) != string::npos; ++i)
		cout<<str[i]<<" ";
	cout<<endl;

	cout<<"alphabetic characters:"<<endl;
	for(string::size_type i=0; (i = str.find_first_not_of(numbers,i)) != string::npos; ++i)
		cout<<str[i]<<" ";
	cout<<endl;
		
	return 0;
}


练习9.48:假定name和numbers的定义如325页所示,numbers.find(name)返回什么?

解答:

返回string::npos;


练习9.49:如果一个字母延伸到中线上,如d或f,则称其有上出头部分(ascender)。如果一个字母延伸到中线之下,如p或g,则称其有下出头部分(decender)。编写程序,读入一个单词文件,输出最长的既不包含上出头部分,也不包含下出头部分的单词。

解答:

#include<iostream>
#include<string>
#include<fstream>

using std::string;using std::ifstream;using std::endl;using std::cout;

int main()
{
	ifstream ifs("word.txt");
	if(!ifs)
		return -1;

	string longest_word;
	for(string word; ifs>>word; )
		if(word.find_first_not_of("aceimnorsuvwxz") == string::npos && 
				                               word.size()>longest_word.size())
			longest_word = word;
	cout<<longest_word<<endl;

	ifs.close();

	return 0;
}


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

解答:

#include<iostream>
#include<string>
#include<vector>

using std::string;using std::vector;using std::cout;using std::endl;

int sum(const vector<string> &v)
{
	int sum = 0;
	for(auto &s:v)
		sum += std::stoi(s);
	return sum;
}

float sum_f(const vector<string> &v)
{
	float sum = 0;
	for(auto &s:v)
		sum += std::stof(s);
	return sum;
}

int main()
{
	vector<string> svec{"0","1","2","3","4.5"};
	cout<<sum(svec)<<endl;
	cout<<sum_f(svec)<<endl;

	return 0;
}


练习9.51:设计一个类,它有三个unsigned成员,分别表示年、月和日。为其编写构造函数,接受一个表示日期的string参数。你的构造函数应该能处理不同数据格式,如January 1,1990、1/1/1990、Jan 1 1990等。

解答:

#include<iostream>
#include<string>
#include<vector>

using std::string;using std::vector;using std::endl;using std::cout;using std::stoi;

class my_date{
	public:
		my_date(const string& md);
		unsigned day;
		unsigned month;
		unsigned year;
};

int main()
{
	my_date md("Jan 1,1990");
	cout<<md.day<<" "
		<<md.month<<" "
		<<md.year<<endl;

	return 0;
}

my_date::my_date(const string& md)
{
	unsigned format = 0;
	// 1/1/1990
	if(md.find_first_of("/") != string::npos)
		format = 0x10;
	
	// Jan 1,1990
	if(md.find_first_of(",") >= 4 && md.find_first_of(",") != string::npos)
		format = 0x01;

	switch(format)
	{
		// format = 1/1/1990
		case 0x10:
			day = stoi(md.substr(0,md.find_first_of("/")));
			month = stoi(md.substr(md.find_first_of("/")+1,md.find_first_of("/")-md.find_last_of("/")));
			year = stoi(md.substr(md.find_last_of("/")+1,4));
			break;

		// format = January 1,1990 or Jan 1,1990
		case 0x01:
			day = stoi(md.substr(md.find_first_of("1234567890"),md.find_first_of(",")-md.find_first_of("1234567890")));
			if(md.find("Jan")<md.size()) month=1;
			if(md.find("Feb")<md.size()) month=2;
			if(md.find("Mar")<md.size()) month=3;
			if(md.find("Apr")<md.size()) month=4;
			if(md.find("May")<md.size()) month=5;
			if(md.find("Jun")<md.size()) month=6;
			if(md.find("Jul")<md.size()) month=7;
			if(md.find("Aug")<md.size()) month=8;
			if(md.find("Sep")<md.size()) month=9;
			if(md.find("Oct")<md.size()) month=10;
			if(md.find("Nov")<md.size()) month=11;
			if(md.find("Dec")<md.size()) month=12;
			year = stoi(md.substr(md.find_last_of(",")+1,4));
			break;
	}
}


练习9.52:使用stack处理括号化的表达式。当你看到一个左括号,将其记录下来。当你在一个左括号之后看到一个右括号,从stack中pop对象,直到遇到左括号,将左括号也一起弹出栈。然后将一个值(括号内 的运算结果)push到栈中,表示一个括号化的(子)表达式已经处理完毕,被其运算结果所替代。

解答:

#include<iostream>
#include<string>
#include<stack>

using std::string;using std::endl;using std::cout;using std::stack;

int main()
{
	stack<char> stk;
	string str{"I am (Groot)"};
	bool find  = false;

	for(const auto &s:str)
	{
		if(s == '(')
		{
			find = true;
			continue;
		}
		else if(s == ')')
			find = false;

		if(find) stk.push(s);
	}

	string repstr;
	while(!stk.empty())
	{
		repstr += stk.top();
		stk.pop();
	}

	str.replace(str.find("(")+1,repstr.size(),repstr);
	cout<<str<<endl;

	return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值