• c++ primer中文版第五版作业第十七章


    仓库地址

    17.1

    tuple it(10,20,30)

    17.2

    tuple,pair> someval("hello",{"hi","hello"},{"hi",10})

    17.3

    TextQuery.h

    #ifndef TEXT_QUERY_H
    #define TEXT_QUERY_H
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    class TextQuery
    {
    public:
    	using line_no=std::vector::size_type;
    	TextQuery(std::ifstream &);
    	std::tuple::size_type>>,std::shared_ptr>> query(const std::string &) const;
    private:
    	std::shared_ptr> file;
    	std::map>> wm;
    };
    inline std::string make_plural(std::size_t count,const std::string &word,const std::string &ending)
    {
            return (count>1)?word+ending:word;
    }
    std::ostream &print(std::ostream &,const std::tuple::size_type>>,std::shared_ptr>> &);
    #endif
    
    • 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

    TextQuery.cpp

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include "TextQuery.h"
    using namespace std;
    TextQuery::TextQuery(ifstream &infile):file(new vector)
    {
    	string text;
    	while(getline(infile,text))
    	{
    		file->push_back(text);
    		size_t line_number=file->size()-1;
    		istringstream line(text);
    		string word;
    		while(line>>word)
    		{
    			shared_ptr> &lines=wm[word];
    			if(!lines)
    				lines.reset(new set);
    			lines->insert(line_number);
    		}
    	}
    }
    std::tuple::size_type>>,std::shared_ptr>> TextQuery::query(const string &sought) const
    {
    	static shared_ptr> nodata(new set);
    	map>>::const_iterator map_it=wm.find(sought);
    	if(map_it==wm.end())
    		return tuple(sought,nodata,file);
    	else
    		return tuple(sought,map_it->second,file);
    }
    std::ostream &print(std::ostream &os,const std::tuple::size_type>>,std::shared_ptr>> &tp)
    {
    	 os<(tp)<<" occurs "<(tp)->size()<<" "<(tp)->size(),"time","s")<(tp)))
                    os<<"\t(line "<(tp)->begin()+num)<
    • 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

    17-3.cpp

    #include 
    #include 
    #include "TextQuery.h"
    using namespace std;
    void runQueries(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))<
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    使用tuple更便捷。

    17.4

    17-4.cpp

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include "Sales_data.h"
    using namespace std;
    typedef tuple::size_type,vector::const_iterator,vector::const_iterator> matches;
    vector findBook(const vector> &files,const string &book)
    {
    	vector ret;
    	for(auto it=files.cbegin();it!=files.cend();++it)
    	{
    		auto found=equal_range(it->cbegin(),it->cend(),book,compareIsbn);
    		if(found.first!=found.second)
    			ret.push_back(make_tuple(it-files.cbegin(),found.first,found.second));
    	}
    	return ret;
    }
    void reportResults(istream &in,ostream &os,vector> &files)
    {
    	string s;
    	while(in>>s)
    	{
    		auto trans=findBook(files,s);
    		if(trans.empty())
    		{
    			cout<(store)<<" sales: "<(store),get<2>(store),Sales_data(s))<> files;
    	Sales_data tmp;
    	ifstream in;
    	string basename="text",line;
    	for(size_t index=0;index!=3;++index)
    	{
    		in.open(basename+to_string(index));
    		vector file;
    		while(in>>tmp)
    			file.push_back(tmp);
    		in.close();
    		files.push_back(file);
    	}
    	reportResults(cin,cout,files);
    	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
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    17.5

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include "Sales_data.h"
    using namespace std;
    typedef pair::size_type,pair::const_iterator,vector::const_iterator>> matches;
    vector findBook(const vector> &files,const string &book)
    {
    	vector ret;
    	for(auto it=files.cbegin();it!=files.cend();++it)
    	{
    		auto found=equal_range(it->cbegin(),it->cend(),book,compareIsbn);
    		if(found.first!=found.second)
    			ret.push_back(make_pair(it-files.cbegin(),found));
    	}
    	return ret;
    }
    void reportResults(istream &in,ostream &os,vector> &files)
    {
    	string s;
    	while(in>>s)
    	{
    		auto trans=findBook(files,s);
    		if(trans.empty())
    		{
    			cout<> files;
    	Sales_data tmp;
    	ifstream in;
    	string basename="text",line;
    	for(size_t index=0;index!=3;++index)
    	{
    		in.open(basename+to_string(index));
    		vector file;
    		while(in>>tmp)
    			file.push_back(tmp);
    		in.close();
    		files.push_back(file);
    	}
    	reportResults(cin,cout,files);
    	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
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    17.6

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include "Sales_data.h"
    using namespace std;
    struct matches
    {
    	vector::size_type index;
    	vector::const_iterator bg;
    	vector::const_iterator ed;
    };
    vector findBook(const vector> &files,const string &book)
    {
    	vector ret;
    	matches tmp;
    	for(auto it=files.cbegin();it!=files.cend();++it)
    	{
    		auto found=equal_range(it->cbegin(),it->cend(),book,compareIsbn);
    		if(found.first!=found.second)
    		{
    			tmp={it-files.cbegin(),found.first,found.second};
    			ret.push_back(tmp);
    		}
    	}
    	return ret;
    }
    void reportResults(istream &in,ostream &os,vector> &files)
    {
    	string s;
    	while(in>>s)
    	{
    		auto trans=findBook(files,s);
    		if(trans.empty())
    		{
    			cout<> files;
    	Sales_data tmp;
    	ifstream in;
    	string basename="text",line;
    	for(size_t index=0;index!=3;++index)
    	{
    		in.open(basename+to_string(index));
    		vector file;
    		while(in>>tmp)
    			file.push_back(tmp);
    		in.close();
    		files.push_back(file);
    	}
    	reportResults(cin,cout,files);
    	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
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    17.7

     使用tuple版本更便捷,使用pair版本稍微复杂一点,自己定义一个类的版本更自由。

    17.8

     主要看类的默认构造函数和operator+是如何定义的,在我这里会得到错误的isbn。

    17.9

    1. 64位的位集,低位为100000,其余高位为0.
    2. 32位的位集,低位为11110110100110110101,其余高位为0.
    3. 如果bstr包含0或1之外的其他字符,构造函数会抛出invalid_argument的异常。否则如果bstr长于8,位集将由bstr的前八位构成,如果bstr长度小于8,那么位集的低位将由bstr构成,而高位被置为0.

    17.10

    #include 
    #include 
    int main(void)
    {
    	std::bitset<22> a("1000000010000100101110");
    	std::cout< b;
    	b^=~a;
    	std::cout<

17.11

 如果只记录真假的话,使用一个位即可记录一对真假,10个问题的真假测验的解答用unsigned char或者位字段或者bitset都可以。但是如果包含100道题的话,那么unsigned long long只保证至少64位,所以最好还是使用bitset或者位字段。

17.12

见此处

#include 
#include 
using namespace std;
void check(bitset<10> &question,size_t index,bool answ)
{
	question.set(index,answ);
}
int main(void)
{
	char ch;
	bool answ;
	bitset<10> question,grade,answer("1000100101");
	for(size_t i=0;i!=question.size();++i)
	{
		cout<<"Enter the answer of question "<

17.13

见17.12

17.14

#include 
#include 
int main(void)
{
	try
	{
		std::regex r("[[:alnums:]].",std::regex::icase);
	}catch(std::regex_error e)
	{
		std::cout<

17.15

#include 
#include 
#include 
int main(void)
{
	std::regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*");
	std::smatch result;
	std::string tmp;
	std::cout<<"Enter a word: ";
	while(std::cin>>tmp)
	{
		if(regex_match(tmp,result,r))
			std::cout<<"error word: "<

17.16

 如果使用[^c]ei进行初始化,那么此模式只能匹配首字母不是c的三个字母组成的单词,其余单词都不能匹配。

#include 
#include 
#include 
int main(void)
{
	std::regex r("[^c]ei");
	std::smatch result;
	std::string tmp;
	std::cout<<"Enter a word: ";
	while(std::cin>>tmp)
	{
		if(regex_match(tmp,result,r))
			std::cout<<"error word: "<

17.17

#include 
#include 
#include 
int main(void)
{
	std::regex r("[[:alpha:]]*[^c]ei[[:alpha:]]*",std::regex::icase);
	std::smatch result;
	std::string tmp,str;
	std::cout<<"Enter some word(ctrl+D to quit): ";
	while(std::cin>>tmp)
	{
		tmp+=" ";
		str+=tmp;
	}
	std::cout<<"all the words wrong: ";
	for(std::sregex_iterator it(str.begin(),str.end(),r),end_it;it!=end_it;++it)
	{
		std::cout<str()<<" ";
	}
	std::cout<

17.18

 没看懂意思,如果只是单纯要排除某些指定的单词的话,在匹配之后输出之前判断一下这个单词是否是要排除的那些单词之一即可,但这并不是一个好办法。

17.19

 首先调用m[4].str()如果m[4]匹配了会返回一个包含输入中匹配部分的string,如果没有匹配就会返回空string。其次,由于||的短路求值属性,会先行判断m[4].matched==0,当它为false时表示m[4]已经匹配了。

17.20

#include 
#include 
bool valid(const std::smatch &m)
{
	if(m[1].matched)
		return m[3].matched&&(m[4].matched==false ||m[4].str()==" ");
	else
		return !m[3].matched && m[4].str()==m[6].str();
}
int main(void)
{
	std::string line;
	std::smatch m;
	std::regex r("(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})");
	while(getline(std::cin,line))
	{
		for(std::sregex_iterator it(line.begin(),line.end(),r),end_it;it!=end_it;++it)
		{
			if(valid(*it))
				std::cout<<"valid: "<str()<str()<

17.21

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
bool valid(const string &str);
string format(const string &str);
struct PersonInfo
{
	string name;
	vector phones;
};
int main(int argc,char *argv[])
{
	string line,word;
	vector people;
	istringstream record;
	ifstream ifst(argv[1]);
	ofstream ofst(argv[2]);
	while(getline(ifst,line))
	{
		PersonInfo info;
		record.clear(record.rdstate()&~record.failbit&~record.eofbit);
		record.str(line);
		record>>info.name;
		while(record>>word)
			info.phones.push_back(word);
		people.push_back(info);
	}
	for(const auto &pi:people)
	{
		ostringstream formatted,badnums;
		for(const auto &ph:pi.phones)
		{
			if(!valid(ph))
				badnums<<" "<

17.22

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
bool valid(const smatch &);
string format(const string &str);
struct PersonInfo
{
	string name;
	vector phones;
};
int main(int argc,char *argv[])
{
	regex r("(\\d{3})([[:space:]]*)(\\d{4})([[:space:]]*)(\\d{4})");
	string line,word;
	vector people;
	istringstream record;
	ifstream ifst(argv[1]);
	ofstream ofst(argv[2]);
	while(getline(ifst,line))
	{
		PersonInfo info;
		record.clear(record.rdstate()&~record.failbit&~record.eofbit);
		record.str(line);
		record>>info.name;
		getline(record,word);
		for(sregex_iterator it(word.begin(),word.end(),r),end_it;it!=end_it;++it)
			info.phones.push_back(it->str());
		people.push_back(info);
	}
	for(const auto &pi:people)
	{
		ostringstream formatted,badnums;
		for(const auto &ph:pi.phones)
		{
				formatted<<" "<

17.23

#include 
#include 
//格式为11111或者11111-1111或者111111111
int main(void)
{
	std::regex r("(\\d{5})([-])?(\\d{4})?");
	std::string line;
	while(getline(std::cin,line))
	{
		for(std::sregex_iterator it(line.begin(),line.end(),r),end_it;it!=end_it;++it)
		{
			if((*it)[3].matched)
				std::cout<str(1)<<"-"<str(3)<str()<

17.24

#include 
#include 
#include 
int main(void)
{
	std::regex r("(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})");
	std::string line;
	std::string fmt="$2.$5.$7 ";
	while(getline(std::cin,line))
	{
		std::cout<

17.25

#include 
#include 
#include 
int main(void)
{
	std::regex r("(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})");
	std::string line;
	std::string fmt="$2.$5.$7";
	while(getline(std::cin,line))
	{
		std::cout<

17.26

#include 
#include 
#include 
#include 
int main(void)
{
	std::vector> result;
	std::regex r("(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})");
	std::string fmt="$2.$5.$7";
	std::string line;
	while(getline(std::cin,line))
	{
		std::vector tmp;
		for(std::sregex_iterator it(line.begin(),line.end(),r),end_it;it!=end_it;++it)
		{
			tmp.push_back(it->format(fmt));
		}
		if(!tmp.empty())
			result.push_back(tmp);
	}
	for(const auto &sv:result)
	{
		if(sv.size()==1)
			std::cout<

17.27

#include 
#include 
#include 
//我也不知道邮编可能有哪些形式
//假设有111111111和1111-11111和1111 11111和1111.11111这些形式
int main(void)
{
	std::string line,fmt="$1-$3 ";
	std::regex r("(\\d{4})([-. ])?(\\d{5})");
	while(getline(std::cin,line))
	{
		line=std::regex_replace(line,r,fmt,std::regex_constants::format_no_copy);
		if(!line.empty())
			std::cout<

17.28

#include 
#include 
unsigned rad()
{
	static std::default_random_engine e;
	static std::uniform_int_distribution u;
	return u(e);
}
int main(void)
{
	for(size_t i=0;i<100;++i)
		std::cout<

17.29

#include 
#include 
#include 
unsigned rad(int sd=time(0))
{
	static std::default_random_engine e(sd);
	static std::uniform_int_distribution u;
	return u(e);
}
int main(void)
{
	for(size_t i=0;i<100;++i)
		std::cout<

17.30

#include 
#include 
#include 
unsigned rad(unsigned sd=time(0),unsigned min=0,unsigned max=9)
{
	static std::default_random_engine e(sd);
	static std::uniform_int_distribution u(min,max);
	return u(e);
}
int main(void)
{
	for(size_t i=0;i<100;++i)
		std::cout<

17.31

 如果循环内定义b、e,那么每步循环都会创建一个新引擎及分布对象,从而每步循环都会生成相同的值。

17.32

 如果在循环内定义resp,那么在while条件判断时resp已经不在其作用域。

17.33

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
std::default_random_engine e(time(0));
std::uniform_int_distribution d;
map> buildMap(ifstream &map_file)
{
	map> trans_map;
	string key,value;
	while(map_file>>key&&getline(map_file,value))
	{
		if(value.size()>1)
			trans_map[key].push_back(value.substr(1));
		else
			throw runtime_error("no rule for "+key);
	}
	return trans_map;
}
const string & transform(const string &str,map> &m)
{
	auto map_it=m.find(str);
	if(map_it==m.end())
		return str;
	else
	{
		return map_it->second[d(e)%(map_it->second.size())];
	}
}
void word_transform(ifstream &map_file,ifstream &input)
{
	auto trans_map=buildMap(map_file);
	string text;
	while(getline(input,text))
	{
		istringstream stream(text);
		string word;
		bool firstword=true;
		while(stream>>word)
		{
			if(firstword)
				firstword=false;
			else
				cout<<" ";
			cout<

17.34

#include 
#include 
#include 
int main(void)
{
	int i=19;
	int a=-19;
	double b=sqrt(2);
	bool c=true;
	std::cout<

17.35

#include 
#include 
#include 
int main(void)
{
	std::cout<

17.36

#include 
#include 
#include 
int main(void)
{
	std::cout<

17.37

 一行的长度超过传递给getline的字符数组的大小时,会导致输入流的条件状态被置为错误,导致后续读入失败。
见此处

#include 
#include 
int main(int argc,char *argv[])
{
	std::ifstream in(argv[1]);
	char *str=new char[100];
	while(in.getline(str,100,'\n'))
	{
		std::cout.write(str,in.gcount());
		std::cout<<'\n';
	}
	delete [] str;
}

17.38

见17.37

17.39

#include 
#include 
int main(int argc,char *argv[])
{
	int ch=0;
	size_t cnt=0;
	std::fstream inout(argv[1],std::fstream::ate|std::fstream::in|std::fstream::out);
	if(!inout)
	{
		std::cerr<<"Unable to open the file!"<
  • 相关阅读:
    扫描电子显微镜(SEM)低真空技术改造以提升观测能力的解决方案
    go get x509:certificate signed by unknown authority
    第五届芜湖机器人展,正运动助力智能装备“更快更准”更智能!
    软件测试/测试开发丨Jenkins Pipeline 学习笔记
    RxJava 实例
    华为---RSTP(四)---RSTP的保护功能简介和示例配置
    【Lua基础 第6章】 Lua 数组、Lua的错误处理、Lua 模块与包、元表(Metatable)和元方法
    【Flask框架】四. Flask框架之 MySQL数据库操作及项目重构
    Nacos安装指南
    如何保护数据和恢复感染[thekeyishere@cock.li].Elbie勒索病毒损失
  • 原文地址:https://blog.csdn.net/fuluoyide312/article/details/136571779