首页 > 编程 > C++ > 正文

C++Primer第五版 第十二章习题答案(21~30)

2019-11-06 07:22:43
字体:
来源:转载
供稿:网友

21:将合法性检查与元素获取的返回语句分离开来,代码更清晰易读,当执行到第二条语句时,已确保p是存在的vector,curr是合法的位置,可安全地获取元素并返回。这种清晰的结构也更有利于修改不同的处理逻辑。

22:将构造函数定义为const即可

23:知识点1:大多数的应用应该使用标准库容器,而不是使用动态分配的数组

知识点2:用new分配的动态数组会返回一个元素类型的指针,而并未得到数组类型的对象

知识点3:动态数组并不是数组类型,不能调用begin()和end()函数,详见106页

知识点4:释放动态数组时,需要在指针名前加 [ ] ,数组中的元素按照逆序销毁

知识点5:字符串字面常量不同于普通的局部变量,具有static duration lifetime,这整个程序的生命周期中都将存在

#include<iostream>  #include<string>  #include<fstream>#include<list>#include<vector> #include<map>  #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件using namespace std;int main(int argc, char**argv)  { 	char *s1 = "abc";	char *s2 = "efg";//字符串字面常量,字符串末尾有空格	string si = "a";	string sl = "b";//标准库string对象	char *p = new char[strlen(s1)+strlen(s2)+1];//必须指明要分配对象的个数	strcpy(p,s1);//复制	strcat(p,s2);//接上	cout<<p<<endl;	strcpy(p,(si+sl).c_str());//必须转换为c类型字符串(c中无string类型)	cout<<p<<endl;	delete [] p;	return 0;} 

24:长度超出后,自动会补上长度:动态数组!

#include<iostream>  #include<string>  #include<fstream>#include<list>#include<vector> #include<map>  #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件using namespace std;int main(int argc, char**argv)  { 	string a;	cin>>a;	char *p = new char[2];	strcpy(p,a.c_str());	cout<<p<<endl;	delete [] p;//一定要记得delete	return 0;}  

25:

delete [] pa;

26:知识点1:new内存分配与对象构造组合在了一起,而allocator将内存分配和对象构造分离,它提供一种类型感知的内存分配方法,它分配的内存时原始的、未构造的知识点2:利用allocator分配内存之后。必须在经过construnct进行构造对象,两个参数分别为:创建对象位置的指针,元素类型的值知识点3:对构造后的元素进行destory操作,销毁对象,deallocator

#include<iostream>  #include<string>  #include<fstream>#include<list>#include<vector> #include<map>  #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件#include<memory>using namespace std;int main(int argc, char**argv)  { // 	string *const p = new string[10];//构造十个空const string// 	string s;// 	string *q = p;// 	while (cin>>s && q != p+10)// 	{// 		*q++ = s;// 	}// 	const size_t size = q-p;//	delete [] p;		string s;	allocator<string> alloc;	auto p = alloc.allocate(10);//用的是(),只分配内存	auto q = p;	while (cin>>s && q != p+10)	{		alloc.construct(q++,s);//创建对象并幅值	}	while(q != p)	{		alloc.destroy(--q);//逐个销毁对象,destory接受一个指针	}	alloc.deallocate(p,10);//分配多少内存,释放多少	return 0;} 

27:主函数.cpp

#include "Chapter12.h"#include <iostream>using namespace std;void runQueries(std::ifstream& infile){	TextQuery tq(infile);	while (true) {	cout << "enter Word to look for, or q to quit: ";	string s;	if (!(cin >> s) || s == "q") break;	PRint(cout, tq.query(s)) << endl;	}}int main(){	ifstream file("1.txt");	runQueries(file);}

头文件.h

#ifndef Cccc//第一次包含本头文件时,#ifndef判断为真,预处理器将处理后面的内容直到#endif,此时的预处理变量Cccc已定义#define Cccc//第二次包含本头文件时,#ifndef判断为假,预处理器将忽略后面的内容#include <string>#include <fstream>#include <map>#include <set>#include <vector>#include <iostream>#include <sstream>using namespace std;class QueryResult;class TextQuery {public:	using LineNo = vector<string>::size_type;	TextQuery(std::ifstream&);	QueryResult query(const string&) const;private:	shared_ptr<vector<string>> input;	std::map<string, shared_ptr<std::set<LineNo>>> result;};class QueryResult {public:	friend std::ostream& print(std::ostream&, const QueryResult&);public:	QueryResult(const string& s, shared_ptr<std::set<TextQuery::LineNo>> set,		shared_ptr<vector<string>> v)		: word(s), nos(set), input(v)	{	}private:	string word;	shared_ptr<std::set<TextQuery::LineNo>> nos;	shared_ptr<vector<string>> input;};std::ostream& print(std::ostream&, const QueryResult&);TextQuery::TextQuery(std::ifstream& ifs) : input(new vector<string>){	LineNo lineNo{0};	for (string line; std::getline(ifs, line); ++lineNo) {		input->push_back(line);		std::istringstream line_stream(line);		for (string text, word; line_stream >> text; word.clear()) {			// avoid read a word followed by punctuation(such as: word, )			std::remove_copy_if(text.begin(), text.end(),				std::back_inserter(word), ispunct);			// use reference avoid count of shared_ptr add.			auto& nos = result[word];			if (!nos) nos.reset(new std::set<LineNo>);			nos->insert(lineNo);		}	}}QueryResult TextQuery::query(const string& str) const{	// use static just allocate once.	static shared_ptr<std::set<LineNo>> nodate(new std::set<LineNo>);	auto found = result.find(str);	if (found == result.end())		return QueryResult(str, nodate, input);	else		return QueryResult(str, found->second, input);}std::ostream& print(std::ostream& out, const QueryResult& qr){	out << qr.word << " occurs " << qr.nos->size()		<< (qr.nos->size() > 1 ? " times" : " time") << std::endl;	for (auto i : *qr.nos)		out << "/t(line " << i + 1 << ") " << qr.input->at(i) << std::endl;	return out;}#endif//只要简单的加上就好了,无视C++中的作用域规则,作用是防止头文件被重复包含

28:

#include <iostream> #include<fstream>#include<sstream>#include <string>  #include <vector>#include<memory>#include<list>#include<map>#include<set>#include<iterator>#include<initializer_list>using namespace std; int main(int argc,char **argv)  {	ifstream in("1.txt");	string line;	vector<string> vec1;	while (getline(in,line))	{		vec1.push_back(line);	}	for (size_t i = 0; i < vec1.size(); ++i)			{		cout<<vec1[i]<<endl;	}//输出文本,做检验	map<string,set<int>> map1;	string s;	cout<<"请输入查找的单词(输入q退出):";	while((cin>>s) && (s != "q"))	{		for (size_t i = 0; i < vec1.size(); ++i)				{			istringstream word(vec1[i]);			string m;			while(word>>m)			{				if (s == m)				{	 				map1[s].insert(i);					break;				}			}		}		cout<<s<<" occours "<<map1[s].size()<<" times "<<endl;		auto it1 = map1[s].begin();		for (it1; it1 != map1[s].end(); ++it1)		{			cout<<"		"<<"(line "<<*it1<<") "<<vec1[*it1]<<endl;		}	}			return 0;} 

补充:利用lambda表达式,可以将while更好的表达,很有用的小技巧!!!

while([&]()->bool{cout<<"请输入查找的单词(输入q退出):";return (cin>>s) && (s != "q");}())

29:do while()是先执行循环体再判断条件,while()是先判断条件再执行循环体,哪个在实际中逻辑更加符合,就用哪个。此题明显do while()更符合30:同27题


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选