当时刚学C++的时候买了这本书,一开始前面看的一知半解,索性就先缓缓,等学完学校的C++课程(中途自己也写了不少c++的代码),一段时间之后又拿起这本书去看,感觉还是挺有滋味的,这本书对我印象中的C++做了很大的扩展,个人认为这本书不太适合刚学C++就去看,而是写了一定的代码,对C++有一个大体的了解之后再去看会别有一番滋味(犇请无视这句话)。在看书的过程中自己也写了上面的课后练习题,现在整理一下,也跟大家分享一下,下面是9~12 15~16章的课后题编程题的答案

(第八章之前的都没保存/(ㄒoㄒ)/~~):

当时保存的时候是按节保存的,比如 练习9.3、练习9.4 练习9.5、练习9.6 是在9.2.1节练习里面的题

9.2.1节练习:

<span style="font-size:18px;">#include <iostream>
#include <vector>std::vector<int>::iterator fun(std::vector<int>::iterator isb,std::vector<int>::iterator ise,int y){while(isb<ise)if(*(isb)==y)return isb;else  isb++;return ise;
}
int main()
{std::vector<int> s={1,2,3};std::vector<int>::iterator is=s.begin();//if(fun(is,s.end(),2)) cout<<"OK"<<endl;is=fun(is,s.end(),2);std::cout<<*is<<std::endl;while(std::cout<<*is<<"#" && (is++)<s.end());return 0;
}
</span>

9.3.1节练习:

#include <iostream>
#include <vector>
#include <list>
#include <deque>int main()
{std::string temp;std::deque<std::string>dq;for(int i=1;i<=3;++i){std::cin>>temp;dq.push_front(temp);}auto x=dq.begin(); //std::deque<std::string>::iterator x;while(x < dq.end() && std::cout<<" "<<*(x++));std::cout<<std::endl;std::list<std::string>l;for(int i=1;i<=3;++i){std::cin>>temp;l.push_front(temp);}auto y=l.begin();while(y!=l.end() && std::cout<<" "<<*(y++)); //list中无 > <操作 使用!=代替std::cout<<std::endl;return 0;
}

9.3.3节练习:

#include <iostream>
#include <vector>
#include <list>
#include <deque>int main()
{int ia[]={0,1,1,2,3,5,8,13,21,55,89};std::vector<int > vec={0,1,1,2,3,5,8,13,21,55,89};std::list<int > lis={0,1,1,2,3,5,8,13,21,55,89};auto i=vec.begin();while(i!=vec.end())if(*i % 2)i=vec.erase(i);else i++;auto j=lis.begin();while(j!=lis.end())if(*j % 2==0)j=lis.erase(j);else j++;for(auto x:vec) std::cout<<" "<<x;std::cout<<std::endl;for(auto x:lis) std::cout<<" "<<x;std::cout<<std::endl;return 0;
}

9.5.3节练习:

练习9.47:

#include <iostream>
#include <algorithm>int main()
{std::string temp("ab2c3d7R4");std::string digit("0123456789");std::string word;for(int i=0;i<24;++i){word+=(char)('a'+i);word+=(char)('A'+i);}std::string::size_type pos=0;while((pos=temp.find_first_of(word,pos))!=std::string::npos) std::cout<<temp[pos++];std::cout<<std::endl;pos=0;while((pos=temp.find_first_of(digit,pos))!=std::string::npos) std::cout<<temp[pos++];std::cout<<std::endl;pos=0;while((pos=temp.find_first_not_of(digit,pos))!=std::string::npos) std::cout<<temp[pos++];std::cout<<std::endl;pos=0;while((pos=temp.find_first_not_of(word,pos))!=std::string::npos) std::cout<<temp[pos++];std::cout<<std::endl;return 0;
}

练习9.49:

#include <iostream>int main()
{std::string temp("bdfghijklpqty");std::string s;while(std::cin>>s){std::string::size_type pos=0;while((pos=s.find_first_not_of(temp,pos))!=std::string::npos)std::cout<<s[pos++];std::cout<<std::endl;}return 0;
}

练习9.50:

#include <iostream>
#include <vector>int main()
{std::vector<std::string > vec={"1","2","3","4","5"};int sum1=0;for(auto x:vec) sum1+=stoi(x);  //codeblock(12.11)报错,vs2012也报,本汪编译器不支持std::cout<<sum1<<std::endl;double sum2=0.0;for(auto x:vec) sum2+=stod(x);std::cout<<sum2<<std::endl;return 0;
}

练习9.51:

#include <iostream>class A{public :A(const std::string s="10/12/1994"){std::string sign=" ,/";auto pos=s.find_first_of(sign);month=s.substr(0,pos);day=s.substr(pos+1,s.find_first_of(sign,pos+1)-pos-1);year=s.substr(s.find_last_of(sign)+1);}void print(){std::cout<<month<<" "<<day<<" "<<year<<std::endl;}private:std::string year,day,month;
};
int main()
{A a;a.print();A b("jan 1/1990");b.print();return 0;
}
/*#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>
#include <numeric>
#include <cstring>using namespace std;
int main()
{int a1[]={1,2,3,4,5,6};int a2[sizeof(a1)/sizeof(a1)];auto ret=copy(begin(a1),end(a1),begin(a2));return 0;
}*/

练习10.1:

#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>using namespace std;
int main()
{std::vector<int > vec={1,2,3,4,5,6,7,12,3,4,6,7,3,6,9,2,6,3,3,3,3,3,3};std::cout<<count(vec.begin(),vec.end(),3)<<std::endl;std::list<std::string > lis={"q","e","sdg","zvgs","123g","545","qwe","uyt","qwe"};std::cout<<count(lis.begin(),lis.end(),"qwe")<<std::endl;return 0;
}

10.2.1节练习:

/*
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>using namespace std;class A{public :A(const string s="1/1/1990"):month("jan"),day("1"),year("1994"){string sign=" ,/";auto pos=s.find_first_of(sign);month=s.substr(0,pos);day=s.substr(pos+1,s.find_first_of(sign,pos+1)-pos-1);year=s.substr(s.find_last_of(sign)+1);}void print(){cout<<month<<" "<<day<<" "<<year<<endl;}private:string year,day,month;
};
int main()
{A a();a.print();// A b("1/1/1990");// b.print();return 0;
}
*/#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
int main()
{std::vector<int > vec={1,2,3,4,5,6,7,8,9};std::cout<<accumulate(vec.cbegin(),vec.cend(),0)<<std::endl;std::vector<std::string > vec_str={"a","b","c","d"};std::cout<<accumulate(vec_str.cbegin(),vec_str.cend(),std::string(""))<<std::endl;//accumulate(,,"");错误 const char* 没有定义+操作//accumulate(,,"hello"); 最后结果是 helloxxxxchar *s=(char *)malloc(10*sizeof(char));char s1[]="heheda",s2[]="heheda";std::cout<<std::equal(s1,s1+strlen(s1),s2)<<std::endl;return 0;
}

10.2.2节练习:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>int main()
{
//10.6int num[]={1,2,3,4,5,6};std::fill_n(std::begin(num),std::end(num)-std::begin(num),0);for(auto x:num) std::cout<<x<<" ";std::cout<<std::endl;//10.7 astd::vector<int > vec;std::list<int >lst;int i;while(std::cin>>i) lst.push_back(i);std::copy(lst.cbegin(),lst.cend(),back_inserter(vec)); //vec未申请空间,所以使用插入迭代器for(auto x:vec) std::cout<<x<<" ";std::cout<<std::endl;//10.7 bstd::vector<int > vecc;vecc.reserve(10);//虽然分配了内存 但size()=0 vecc.begin()==vecc.end() capacity()=10std::fill_n(vecc.begin(),10,0);for(auto x:vecc) std::cout<<x<<" ";std::cout<<std::endl;return 0;
}

10.2.3节练习:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>void elimDups(std::vector<std::string > &vec){std::sort(vec.begin(),vec.end());auto uni=std::unique(vec.begin(),vec.end()); //把重复单词忘末尾放,返回指向不重复范围的后一个迭代器vec.erase(uni,vec.end());for(auto x:vec) std::cout<<x<<" ";std::cout<<std::endl;
}
int main()
{std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};elimDups(vec);return 0;
}
// the quick red fox jumps over the slow red turtle

10.3.1节练习:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>void elimDups(std::vector<std::string > &vec){std::sort(vec.begin(),vec.end());auto uni=std::unique(vec.begin(),vec.end()); //把重复单词忘末尾放,返回指向不重复范围的后一个迭代器vec.erase(uni,vec.end());for(auto x:vec) std::cout<<x<<" ";std::cout<<std::endl;
}
bool isShortter(std::string a,std::string b){return a.size()<b.size();
}bool islessfive(const std::string &a){return a.length()<5;
}int main()
{std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};elimDups(vec);std::stable_sort(vec.begin(),vec.end(),isShortter);for(auto x:vec) std::cout<<x<<" ";std::cout<<std::endl;auto iter=partition(vec.begin(),vec.end(),islessfive);while(iter!=vec.end())std::cout<<*iter++<<" ";std::cout<<std::endl;return 0;
}
// the quick red fox jumps over the slow red turtle

10.3.2节练习:

练习10.16:

#include <iostream>
#include <vector>
#include <algorithm>void elimDups(std::vector<std::string > &vec){std::sort(vec.begin(),vec.end());auto uni=std::unique(vec.begin(),vec.end()); //把重复单词忘末尾放,返回指向不重复范围的后一个迭代器vec.erase(uni,vec.end());std::cout<<"after unique_sort and erase :"<<std::endl;for(auto x:vec) std::cout<<x<<" ";std::cout<<std::endl;
}int main()
{//10.15int x,y;std::cin>>x>>y;auto fun2=[x](const int y){return x+y;};std::cout<<fun2(y)<<std::endl;//10.16std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};elimDups(vec);std::stable_sort(vec.begin(),vec.end(),[](const std::string &a,const std::string &b){return a.size()<b.size();});std::cout<<"after stable_sort:"<<std::endl;for(auto x:vec) std::cout<<x<<" ";std::cout<<std::endl;int n;std::cin>>n;auto iter=find_if(vec.begin(),vec.end(),[n](const std::string &s){return s.size()>=n;});auto count=vec.end()-iter;for_each(iter,vec.end(),[](const std::string &s){std::cout<<s<<" ";});std::cout<<std::endl;return 0;
}

练习10.18:

#include <iostream>
#include <vector>
#include <algorithm>void elimDups(std::vector<std::string > &vec){std::sort(vec.begin(),vec.end());auto uni=std::unique(vec.begin(),vec.end()); //把重复单词忘末尾放,返回指向不重复范围的后一个迭代器vec.erase(uni,vec.end());std::cout<<"after unique_sort and erase :"<<std::endl;for(auto x:vec) std::cout<<x<<" ";std::cout<<std::endl;
}int main()
{std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};elimDups(vec);stable_sort(vec.begin(),vec.end(),[](const std::string &a,const std::string &b){return a.size()<b.size();});std::cout<<"after stable_sort:"<<std::endl;for(auto x:vec) std::cout<<x<<" ";std::cout<<std::endl;int n;std::cin>>n;auto iter=partition(vec.begin(),vec.end(),[n](const std::string &s){return s.size()<n;});auto count=vec.end()-iter;for_each(iter,vec.end(),[](const std::string &s){std::cout<<s<<" ";});std::cout<<std::endl;return 0;
}

10.3.3节练习:

#include <iostream>
#include <vector>
#include <algorithm>int main()
{std::vector<std::string> vec={"the","quick","red","fox","jumps","over","the","slow","red","turtle"};auto x=count_if(vec.begin(),vec.end(),[](const std::string &s){return s.size()>=6;});std::cout<<x<<std::endl;int y=0;auto def=[=]()mutable{if(y==0) return true;else{--y;return false;}};return 0;
}

10.3.4节练习:

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>using namespace std::placeholders; // bind_n操作bool check_size(const int &x,std::string::size_type sz){return x>=sz;}int main()
{std::vector<int > vec={1,3,6,8,0,3,5,12,4,2};std::string s="woqu";auto f=bind(check_size,_1,s.size());for(auto x:vec)if(f(x)){std::cout<<x<<std::endl;break;}return 0;
}

10.4.1节练习:

#include <iostream>
#include <list>
#include <vector>
#include <functional>
#include <algorithm>int main()
{
//10.27std::list<int > lst={1,2,2,2,2,2,2,2,6,8};std::list<int > lst1;unique_copy(lst.begin(),lst.end(),back_inserter(lst1));std::cout<<"old array:";for_each(lst.begin(),lst.end(),[](const int &x){std::cout<<x<<" ";});std::cout<<std::endl;std::cout<<"new array:";for_each(lst1.begin(),lst1.end(),[](const int &x){std::cout<<x<<" ";});std::cout<<std::endl;//10.28
//其中front_inserter报错   ŝinserter 复制失败std::vector <int > vec={1,2,3,4,5,6,7,8,9};std::vector <int > front_vec,back_vec,rand_vec;auto iter=vec.begin();//copy(vec.begin(),vec.end(),front_inserter(front_vec));copy(vec.begin(),vec.end(),back_inserter(back_vec));copy(vec.begin(),vec.end(),inserter(vec,iter));// std::cout<<"front:";//for_each(front_vec.begin(),front_vec.end(),[](const int &x){std::cout<<x<<" ";});std::cout<<std::endl;std::cout<<"back:";for_each(back_vec.begin(),back_vec.end(),[](const int &x){std::cout<<x<<" ";});std::cout<<std::endl;std::cout<<"rand:";for_each(rand_vec.begin(),rand_vec.end(),[](const int &x){std::cout<<x<<" ";});std::cout<<std::endl;return 0;
}

10.4.2节练习:

#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include <algorithm>//10.33
void fun(const std::string &inf_file,const std::string &outf1_file,const std::string &outf2_file){std::ifstream inf;inf.open(inf_file);std::istream_iterator<int > inf_iter(inf),eof;std::ofstream outf1;outf1.open(outf1_file);std::ofstream outf2;outf2.open(outf2_file);std::ostream_iterator<int > outf1_iter(outf1),outf2_iter(outf2);while(inf_iter!=eof){if((*inf_iter)%2) outf1<<*inf_iter;else outf2<<*inf_iter;inf_iter++;}std::cout<<"从文件\""<<inf_file<<"\"中读取数字,奇数已存入\""<<outf1_file<<"\"中,偶数已存入\""<<outf2_file<<"\"中"<<std::endl;inf.close();outf1.close();outf2.close();
}int main()
{//10.29std::ifstream inf;inf.open("test.txt");std::istream_iterator<std::string > in_iter(inf); //in_ter 从文件流inf中读取类型为std::string的值std::istream_iterator<std::string > eof;  //文件结束位置std::vector<std::string> vec(in_iter,eof); //把文件的字符串读入vec中auto iter=vec.begin();while(iter!=vec.end()) std::cout<<*iter++<<" ";std::cout<<std::endl;inf.close();//10.30std::istream_iterator<int > in(std::cin); //in从输入流cin中读取类型为int的值std::istream_iterator<int > eof2;  //输入流结束位置std::vector<int > vec2(in,eof2);   //输入的数据读入vec2sort(vec2.begin(),vec2.end()); //排序std::ostream_iterator<int > out(std::cout," ");  //把类型为int的值写到输出流out中,每个值后加空格copy(vec2.begin(),vec2.end(),out);//vec2的值读出到out中std::cout<<std::endl;std::ostream_iterator<int > out2(std::cout," ");unique_copy(vec2.begin(),vec2.end(),out2); //不重复的复制std::cout<<std::endl;//10.33fun("num_in.txt","num_out1.txt","num_out2.txt");return 0;
}

10.4.3节练习:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>int main()
{//10.34 10.35std::vector <int > vec={1,2,3,4,5,6,7,8,9};std::vector<int >::reverse_iterator reiter=vec.rbegin(); //反向迭代器while(reiter!=vec.rend()) std::cout<<*reiter++<<" ";std::cout<<std::endl;std::vector<int >::iterator iter=vec.begin();    //普通迭代器while(iter!=vec.end()) std::cout<<*iter++<<" ";std::cout<<std::endl;//10.36std::list<int > lis={1,2,3,0,6,4,0,1,3,2}; //查找最后一个0,返回其迭代器std::list<int >::reverse_iterator lis_reiter=find(lis.rbegin(),lis.rend(),0);std::cout<<*lis_reiter<<std::endl;//10.37std::vector <int > vec2={1,2,3,4,5,6,7,8,9,10}; // 取其中 3~7 的位置复制给std::liststd::list <int> lis2;auto vec2_iter=vec2.begin();copy(vec2_iter+2,vec2_iter+7,back_inserter(lis2));//后插迭代器实现for(auto x:lis2) std::cout<<x<<" ";std::cout<<std::endl;return 0;
}

11.1.1节练习:

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>//algorithm提供的string转换字母大小写函数写法
std::string fun(std::string &s){transform(s.begin(),s.end(),s.begin(), ::tolower);std::string s2;for(auto x:s) if(islower(x)) s2+=x; //去标点return s2;
}
int main()
{std::map<std::string  ,size_t > m;std::string word;while(std::cin>>word && word!="end") m[fun(word)]++;for(const auto &x:m)std::cout<<x.first<<" : "<<x.second<<std::endl;return 0;
}

11.2.1节练习:

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>int main()
{std::map<std::string ,std::vector<std::string > > name;std::string first_name,last_name;while(std::cin>>first_name>>last_name && first_name!="end")(name[first_name]).push_back(last_name);for(auto x:name){std::cout<<x.first<<": "<<std::endl;for(auto y:x.second) std::cout<<y<<" ";std::cout<<std::endl;}return 0;
}
/*
李 胜
李 冰冰
李 连杰
刘 韶
刘 氓
刘 星
刘 亦菲
张 三丰
张 天泽
张 晓红
end e
*/

11.2.3节练习~练习11.12、练习11.13:

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>int main()
{//11.12 11.13std::vector <std::pair<std::string ,int> > vec1,vec2,vec3;std::pair<std::string ,int> pa;while(std::cin>>pa.first>>pa.second){vec1.push_back({pa.first,pa.second});vec2.push_back(std::pair<std::string,int>(pa.first,pa.second));vec3.push_back(pa);}for(auto x:vec1) std::cout<<x.first<<" "<<x.second<<std::endl;return 0;
}

练习11.14:

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility> //pair
#include <map>int main()
{//11.14std::map<std::string ,std::vector<std::pair<std::string,std::string> > > name;std::string first_name;std::pair<std::string,std::string> last_name;while(std::cin>>first_name>>last_name.first>>last_name.second && first_name!="end")(name[first_name]).push_back(last_name);for(auto x:name){std::cout<<x.first<<": "<<std::endl;for(auto y:x.second) std::cout<<y.first<<" "<<y.second<<" ";std::cout<<std::endl;}return 0;
}

11.3.2节练习:

#include <iostream>
#include <algorithm>
#include <map>int main()
{//11.20std::map<std::string ,size_t > word_count;std::string word;while(std::cin>>word && word!="end"){std::pair< std::map<std::string ,size_t>::iterator,bool> ite=word_count.insert({word,1});if(!ite.second) ite.first->second++;}for(auto x:word_count)std::cout<<x.first<<" : "<<x.second<<std::endl;//11.23std::multimap<std::string ,std::string> name;std::string first_name,last_name;while(std::cin>>first_name>>last_name && first_name!="end")name.insert({first_name,last_name});for(auto x:name)std::cout<<x.first<<": "<<x.second<<std::endl;return 0;
}

11.3.5节练习:

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <utility>int main()
{//11.31std::multimap<std::string ,std::string > book={{"oyy","c++ prime"},{"oyy","java plus"},{"oyy","english"},{"awei","math"},{"awei","computer"},{"baobao","taijiong"},{"baobao","gangjiong"},};std::string find_name="baoba";auto ite=book.find(find_name);while(ite!=book.end() && ite->first==find_name){ite=book.erase(ite);}for(auto x:book) std::cout<<x.first<<" "<<x.second<<std::endl;return 0;
}

11.3.6节练习:

#include <iostream>
#include <map>
#include <fstream>
#include <sstream>int main()
{
//11.33//读取转换规则std::ifstream readfile("test1.txt");std::map<std::string ,std::string> tran;std::string word_first,word_second,temp;while(readfile>>word_first && getline(readfile,word_second))tran[word_first]=word_second.length()==0?word_first:word_second.substr(1);//读取要转的内容std::ifstream readfile2("test2.txt");std::string sentc,word;while(getline(readfile2,sentc)){std::istringstream in(sentc);while(in>>word){if(tran.find(word)!=tran.end()) std::cout<<tran[word]<<" ";else std::cout<<word<<" ";}std::cout<<std::endl;}return 0;
}/*
test1.txt
brb be right back
k okay?
justkey
y why
r are
u you
pic picture
thk thanks!
l8r latertest2.txt
where r u
y dont u send me a pic
k thk l8r*/

12.1.1节练习:

#include <iostream>
#include <vector>
#include <initializer_list>
#include <memory>
#include <stdexcept>//12.2
class StrBlob{typedef std::vector<std::string>  vstring;public:StrBlob():data(std::make_shared<vstring>()){}StrBlob(std::initializer_list<std::string > lis):data(std::make_shared<vstring>(lis)){}vstring::size_type size()const {return data->size();}void push_back(const std::string &s){data->push_back(s);}void pop_back(){check(0,"pop on empty StrBlob");data->pop_back();}std::string &front(){check(0,"front on empty StrBlob");return data->front();}std::string &back(){check(0,"back on empty StrBlob");return data->back();}private:std::shared_ptr<vstring> data; // emoryvoid check(vstring::size_type i,const std::string &s)const {if(data->size()<=i) throw std::out_of_range(s); // stdexcept}
};
int main()
{//12.1StrBlob b1{};{StrBlob b2={"a","an","the"};b1=b2;b2.push_back("about");}std::cout<<b1.back()<<std::endl;StrBlob b3{"wo","qu"};std::cout<<b3.back()<<std::endl;return 0;
}

12.1.2节练习:

#include <iostream>
#include <vector>
#include <memory>//12.6
std::vector<int > *new_vecint(){return new std::vector<int>;
}
void read_data(std::istream &in,std::vector<int> *&pv){ //普通指针 引用指针int x;in>>x;pv->push_back(x);
}void print(std::vector<int> *&pv){for(auto x:*pv) std::cout<<x<<" ";std::cout<<std::endl;delete(pv);pv=nullptr;
}//12.7
std::shared_ptr <std::vector<int > > ptr_vecint(){ //智能指针return std::make_shared<std::vector<int > > ();//return  shared_ptr<vector<int >> (new vector<int>(p));
}void ptr_read_data(std::istream &in,std::shared_ptr<std::vector<int > > &spv){int x;in>>x;spv->push_back(x);
}
void ptr_print(std::shared_ptr<std::vector<int > > spv){for(auto x:*spv) std::cout<<x<<" ";std::cout<<std::endl;
}int main()
{//12.6auto pv=new_vecint();for(int i=1;i<=3;++i) read_data(std::cin,pv);print(pv);//12.7auto spv=ptr_vecint();for(int i=1;i<=3;++i) ptr_read_data(std::cin,spv);ptr_print(spv);return 0;
}

12.1.6节练习:

#include <iostream>
#include <vector>
#include <initializer_list>
#include <memory>
#include <stdexcept>
#include <fstream>
#include <sstream>class StrBlob{
typedef std::vector<std::string>  vstring;
public:friend class StrBlobPtr;StrBlob():data(std::make_shared<vstring>()){}StrBlob(std::initializer_list<std::string > lis):data(std::make_shared<vstring>(lis)){}vstring::size_type size()const {return data->size();}void push_back(const std::string &s){data->push_back(s);}void pop_back(){check(0,"pop on empty StrBlob");data->pop_back();}std::string &front(){check(0,"front on empty StrBlob");return data->front();}std::string &back(){check(0,"back on empty StrBlob");return data->back();}
private:std::shared_ptr<vstring> data; // memoryvoid check(vstring::size_type i,const std::string &s)const {if(data->size()<=i) throw std::out_of_range(s); //stdexcept}
};
//12.19 12.20
class StrBlobPtr{
typedef std::vector<std::string>  vstring;
public :StrBlobPtr():curr(0){}StrBlobPtr(StrBlob &a,size_t sz=0):wptr(a.data),curr(sz){}std::string &deref() const {auto p=check(curr,"dereference past end");return (*p)[curr];}StrBlobPtr& incur(){check(curr,"increment past end of StrBlobPtr");++curr;return *this;}bool empty(){if(curr < wptr.lock()->size()) return false;return true;}
private:std::shared_ptr<vstring> check(size_t i,const std::string &msg)const {auto ret=wptr.lock();if(!ret) throw std::runtime_error("unbound StrBlobPtr");if(ret->size() <= i)throw std::out_of_range(msg);return ret;}std::weak_ptr<vstring> wptr;size_t curr;
};int main()
{//12.20std::ifstream in("in.txt");std::string word_s;StrBlob sb;while(getline(in,word_s)){   //从文件读入数据std::stringstream sin(word_s);std::string word;while(sin>>word) sb.push_back(word);sb.push_back("\n");}StrBlobPtr sbp(sb);  //使用StrBlob 指针类型输出StrBlobwhile(!sbp.empty()){std::cout<<sbp.deref()<<" ";sbp.incur();}return 0;
}
/*
in.txt
i think we should do it if you don't mind.
so what do you want to do?
*/

12.2.1节练习:

#include <iostream>
#include <memory>
#include <algorithm>
#include <cstring>
#include <iterator>int main()
{//12.23char sc1[]="woqu",sc2[]=" nimeide";char *q=new char[strlen(sc1)+strlen(sc2)+1];strcpy(q,sc1);strcat(q,sc2);std::cout<<q<<std::endl;std::string s1="woqu",s2=" nimeide";std::cout<<s1+s2<<std::endl;delete [] q;// need to tell the size. 12.24std::cout << "How long do you want the string? ";int size(0);std::cin >> size;char* input = new char[size + 1]();std::cin.ignore(); //读取多余回车std::cout << "input the string: ";std::cin.get(input, size + 1);std::cout << input;delete[] input;return 0;
}

12.2.2节练习:

#include <iostream>
#include <memory>//12.26
int main()
{int n;std::cout<<"please input size:";std::cin>>n;std::cin.ignore();std::allocator<std::string > t;  //定义类型对象auto const p = t.allocate(n); //申请内存auto q=p;std::string word;while(q!=p+n && std::cin>>word) t.construct(q++,word); //调用构造函数while(q!=p){std::cout<<*--q<<std::endl;t.destroy(q);  //调用析构函数,释放对象}t.deallocate(p,n); //释放内存return 0;
}

12.3.1节练习:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>//12.28
typedef std::vector<std::string >::size_type line;int main()
{std::vector<std::string > text;std::map<std::string ,std::set<line> > sign;std::string file_name;std::cout<<"enter file name : "<<std::endl;std::cin>>file_name;std::cin.ignore();std::ifstream file_input(file_name);std::string senten,word;while(getline(file_input,senten)){ //读入文件内容text.push_back(senten);std::stringstream word_in(senten);line len=text.size();while(word_in>>word) sign[word].insert(len);}while(true){  //查询std::cout<<"enter the query word and enter q to quit : ";std::cin>>word;std::cin.ignore();if(word=="q") break;auto loc=sign.find(word);if(loc==sign.cend()) std::cout<<"not find "<<word<<std::endl;else {std::cout<<word<<" : "<<std::endl;for(auto x:loc->second)std::cout<<"(line "<<x<<") : "<<text[x-1]<<std::endl;}}return 0;
}

12.3.2节练习:

练习12.30:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>
//12.30 同12.27
class TextQuery;
class QueryResult;
using line=std::vector<std::string>::size_type;
//文件查询类,存错整个文件内容 以及每个单词出现的行数   定义查询函数返回一个查询结果类
class TextQuery{
public ://构造函数 获取一个文件输入对象 构造 sign p_textTextQuery(std::ifstream& in):p_text(new std::vector<std::string >){std::string senten;  //读取每行的句子while(getline(in,senten)){p_text->push_back(senten);auto len=p_text->size();std::stringstream word_in(senten);std::string word;while(word_in>>word){auto isok=sign.find(word);//若该单词还为出现过,申请新的空间if(isok==sign.cend()) sign[word].reset(new std::set<line>);sign[word]->insert(len);}}}//该函数的定义必须在QueryResult 完整定义后定义,这里只做声明QueryResult query(const std::string &s)const ;
private :std::shared_ptr<std::vector<std::string > > p_text;  //存内容std::map<std::string,std::shared_ptr<std::set<line> > > sign; //存每个单词所在行位置数
};//查询结果类 包括查询的单词 以及该单词所在的所有行数 单词所在行的句子(即必须获取所有内容)
class QueryResult{
private:std::string word;   //查询的单词std::shared_ptr<std::set<line> > p_line; //该单词的行号std::shared_ptr<std::vector<std::string> >p_text; //存句子
public ://print要使用里面的成员friend std::ostream& print(std::ostream& out,const QueryResult& qr);QueryResult(std::string s,std::shared_ptr<std::set<line> > pl,std::shared_ptr<std::vector<std::string> > pv):word(s),p_line(pl),p_text(pv){}
};
QueryResult TextQuery::query(const std::string &s)const{std::shared_ptr<std::set<line> > null_ptr(new std::set<line> );auto isok=sign.find(s);//若未找到,返回第二个参数为新申请的初始化的空间if(isok==sign.cend()) return QueryResult(s,null_ptr,p_text);else return QueryResult(s,isok->second,p_text);
}
std::ostream& print(std::ostream& out,const QueryResult &qr){out<<qr.word<<" : "<<std::endl;for(auto x:*qr.p_line) out<<"(line "<<x<<" ): "<<qr.p_text->at(x-1)<<std::endl;return out;
}
void runQueries(std::ifstream &infile){TextQuery tq(infile);while(true){std::cout<<"enter word to look for, or q to quit: ";std::string s;if(!(std::cin>>s) || s=="q") break;print(std::cout,tq.query(s))<<std::endl;}
}
int main()
{std::ifstream in("in.txt");runQueries(in);return 0;
}

练习12.32:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>
#include <stdexcept>
//12.32
class StrBlob{typedef std::vector<std::string>  vstring;public:StrBlob():data(std::make_shared<vstring>()){}StrBlob(std::initializer_list<std::string > lis):data(std::make_shared<vstring>(lis)){}vstring::size_type size()const {return data->size();}void push_back(const std::string &s){data->push_back(s);}void pop_back(){check(0,"pop on empty StrBlob");data->pop_back();}std::string &front(){check(0,"front on empty StrBlob");return data->front();}std::string &back(){check(0,"back on empty StrBlob");return data->back();}std::string at(int x){return data->at(x);}
private:std::shared_ptr<vstring> data; // emoryvoid check(vstring::size_type i,const std::string &s)const {if(data->size()<=i) throw std::out_of_range(s); // stdexcept}
};class TextQuery;
class QueryResult;
using line=std::vector<std::string>::size_type;
//文件查询类,存错整个文件内容 以及每个单词出现的行数   定义查询函数返回一个查询结果类
class TextQuery{
public ://构造函数 获取一个文件输入对象 构造 sign p_textTextQuery(std::ifstream& in):p_text(new StrBlob){std::string senten;  //读取每行的句子while(getline(in,senten)){p_text->push_back(senten);auto len=p_text->size();std::stringstream word_in(senten);std::string word;while(word_in>>word){auto isok=sign.find(word);//若该单词还为出现过,申请新的空间if(isok==sign.cend()) sign[word].reset(new std::set<line>);sign[word]->insert(len);}}}//该函数的定义必须在QueryResult 完整定义后定义,这里只做声明QueryResult query(const std::string &s)const ;
private :std::shared_ptr<StrBlob > p_text;  //存内容std::map<std::string,std::shared_ptr<std::set<line> > > sign; //存每个单词所在行位置数
};//查询结果类 包括查询的单词 以及该单词所在的所有行数 单词所在行的句子(即必须获取所有内容)
class QueryResult{
private:std::string word;   //查询的单词std::shared_ptr<std::set<line> > p_line; //该单词的行号std::shared_ptr<StrBlob >p_text; //存句子
public ://print要使用里面的成员friend std::ostream& print(std::ostream& out,const QueryResult& qr);QueryResult(std::string s,std::shared_ptr<std::set<line> > pl,std::shared_ptr<StrBlob > pv):word(s),p_line(pl),p_text(pv){}
};
QueryResult TextQuery::query(const std::string &s)const{std::shared_ptr<std::set<line> > null_ptr(new std::set<line> );auto isok=sign.find(s);//若未找到,返回第二个参数为新申请的初始化的空间if(isok==sign.cend()) return QueryResult(s,null_ptr,p_text);else return QueryResult(s,isok->second,p_text);
}
std::ostream& print(std::ostream& out,const QueryResult &qr){out<<qr.word<<" : "<<std::endl;for(auto x:*qr.p_line)out<<"(line "<<x<<" ): "<<qr.p_text->at(x-1)<<std::endl;return out;
}
void runQueries(std::ifstream &infile){TextQuery tq(infile);while(true){std::cout<<"enter word to look for, or q to quit: ";std::string s;if(!(std::cin>>s) || s=="q") break;print(std::cout,tq.query(s))<<std::endl;}
}int main()
{std::ifstream in("in.txt");runQueries(in);return 0;
}

练习12.33:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>
//12.30 同12.27class TextQuery;
class QueryResult;
using line=std::vector<std::string>::size_type;
//文件查询类,存错整个文件内容 以及每个单词出现的行数   定义查询函数返回一个查询结果类
class TextQuery{
public ://构造函数 获取一个文件输入对象 构造 sign p_textTextQuery(std::ifstream& in):p_text(new std::vector<std::string >){std::string senten;  //读取每行的句子while(getline(in,senten)){p_text->push_back(senten);auto len=p_text->size();std::stringstream word_in(senten);std::string word;while(word_in>>word){auto isok=sign.find(word);//若该单词还为出现过,申请新的空间if(isok==sign.cend()) sign[word].reset(new std::set<line>);sign[word]->insert(len);}}}//该函数的定义必须在QueryResult 完整定义后定义,这里只做声明QueryResult query(const std::string &s)const ;
private :std::shared_ptr<std::vector<std::string > > p_text;  //存内容std::map<std::string,std::shared_ptr<std::set<line> > > sign; //存每个单词所在行位置数
};//查询结果类 包括查询的单词 以及该单词所在的所有行数 单词所在行的句子(即必须获取所有内容)
class QueryResult{
private:std::string word;   //查询的单词std::shared_ptr<std::set<line> > p_line; //该单词的行号std::shared_ptr<std::vector<std::string> >p_text; //存句子
public ://print要使用里面的成员friend std::ostream& print(std::ostream& out,const QueryResult& qr);QueryResult(std::string s,std::shared_ptr<std::set<line> > pl,std::shared_ptr<std::vector<std::string> > pv):word(s),p_line(pl),p_text(pv){}std::set<line >::iterator begin(){   //beginreturn p_line->begin();}std::set<line >::iterator end(){   //endreturn p_line->end();}std::shared_ptr<std::vector<std::string> > get_file(){ //get_filereturn p_text;}
};
QueryResult TextQuery::query(const std::string &s)const{std::shared_ptr<std::set<line> > null_ptr(new std::set<line> );auto isok=sign.find(s);//若未找到,返回第二个参数为新申请的初始化的空间if(isok==sign.cend()) return QueryResult(s,null_ptr,p_text);else return QueryResult(s,isok->second,p_text);
}
std::ostream& print(std::ostream& out,const QueryResult &qr){out<<qr.word<<" : "<<std::endl;for(auto x:*qr.p_line) out<<"(line "<<x<<" ): "<<qr.p_text->at(x-1)<<std::endl;return out;
}
void runQueries(std::ifstream &infile){TextQuery tq(infile);while(true){std::cout<<"enter word to look for, or q to quit: ";std::string s;if(!(std::cin>>s) || s=="q") break;print(std::cout,tq.query(s))<<std::endl;}
}int main()
{return 0;
}

15.2.1节练习:

#include <iostream>//15.3
class Quote{
public :Quote()=default;Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}std::string isbn()const {return bookNo;}virtual double net_price(std::size_t n) const {return n*price;}friend double print_total(std::ostream&,const Quote&,size_t );
private:std::string bookNo;
protected:double price=0.0;
};double print_total(std::ostream &os,const Quote &item,size_t n){double ret=item.net_price(n);os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;return ret;
}
int main()
{Quote q("c++ prime",150);print_total(std::cout,q,3);return 0;
}

15.2.2节练习:

#include <iostream>
#include <cstdio>//15.5 15.6 15.7
class Quote{
public :Quote()=default;Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}std::string isbn()const {return bookNo;}virtual double net_price(std::size_t n) const {return n*price;}friend double print_total(std::ostream&,const Quote&,size_t );
private:std::string bookNo;
protected:double price=0.0;
};class Bulk_quote:public Quote{
public :Bulk_quote()=default;Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):Quote(book,sales_price),min_num(num),discount(disc){};double net_price(std::size_t n) const{if(n>=min_num) return n*price*discount;else return n*price;}
private:std::size_t min_num;double discount;
};class huodong_quote:public Quote{
public :huodong_quote()=default;huodong_quote(const std::string book,double sales_price,std::size_t num,double disc):Quote(book,sales_price),max_num(num),discount(disc){}double net_price(std::size_t n)const {if(n<=max_num) return n*price*discount;else return net_price(max_num)+(n-max_num)*price;}
private:double discount;size_t max_num;
};
double print_total(std::ostream &os,const Quote &item,size_t n){double ret=item.net_price(n);os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;return ret;
}int main()
{Bulk_quote b("math",20,5,0.5);print_total(std::cout,b,4);print_total(std::cout,b,5);huodong_quote h("高数",20,5,0.5);print_total(std::cout,h,5);print_total(std::cout,h,6);return 0;
}

15.3节练习:

#include <iostream>
#include <cstdio>//15.11  debug()
class Quote{
public :Quote()=default;Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}std::string isbn()const {return bookNo;}virtual double net_price(std::size_t n) const {return n*price;}friend double print_total(std::ostream&,const Quote&,size_t );virtual void debug(){std::cout<<"类成员及类型如下所示:"<<std::endl;std::cout<<"string : bookNo"<<std::endl;std::cout<<"double : price"<<std::endl;}
private:std::string bookNo;
protected:double price=0.0;
};class Bulk_quote:public Quote{
public :Bulk_quote()=default;Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):Quote(book,sales_price),min_num(num),discount(disc){};double net_price(std::size_t n) const{if(n>=min_num) return n*price*discount;else return n*price;}void debug()override{Quote::debug();std::cout<<"size_t : min_num"<<std::endl;std::cout<<"double : discount"<<std::endl;}
private:std::size_t min_num;double discount;
};class huodong_quote:public Quote{
public :huodong_quote()=default;huodong_quote(const std::string book,double sales_price,std::size_t num,double disc):Quote(book,sales_price),max_num(num),discount(disc){}double net_price(std::size_t n)const {if(n<=max_num) return n*price*discount;else return net_price(max_num)+(n-max_num)*price;}void debug()override{Quote::debug();std::cout<<"size_t : max_num"<<std::endl;std::cout<<"double : discount"<<std::endl;}
private:double discount;size_t max_num;
};
double print_total(std::ostream &os,const Quote &item,size_t n){double ret=item.net_price(n);os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;return ret;
}int main()
{Bulk_quote b("math",20,5,0.5);huodong_quote h("数学",20,5,0.5);b.debug();std::cout<<std::endl;h.debug();return 0;
}

15.4节练习:

#include <iostream>
#include <cstdio>//15.15 15.16
class Quote{
public :Quote()=default;Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}std::string isbn()const {return bookNo;}virtual double net_price(std::size_t n) const {return n*price;}friend double print_total(std::ostream&,const Quote&,size_t );
private:std::string bookNo;
protected:double price=0.0;
};
double print_total(std::ostream &os,const Quote &item,size_t n){double ret=item.net_price(n);os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;return ret;
}
class Disc_quote:public Quote{
public :Disc_quote()=default;Disc_quote(const std::string &book,double sales_price,std::size_t n,double disc):Quote(book,sales_price),off_num(n),discount(disc){}double net_price(size_t)const =0;  //´¿Ð麯Êý
protected:size_t off_num;double discount;
};
class Bulk_quote:public Disc_quote{
public :Bulk_quote()=default;Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):Disc_quote(book,sales_price,num,disc){};double net_price(std::size_t n) const override{if(n>=off_num) return n*price*discount;else return n*price;}
};class huodong_quote:public Disc_quote{
public :huodong_quote()=default;huodong_quote(const std::string book,double sales_price,std::size_t num,double disc):Disc_quote(book,sales_price,num,disc){}double net_price(std::size_t n)const override{if(n<=off_num) return n*price*discount;else return net_price(off_num)+(n-off_num)*price;}
};
int main()
{Bulk_quote b("高数",20,5,0.5);huodong_quote h("线代",20,5,0.5);print_total(std::cout,b,6);print_total(std::cout,h,6);return 0;
}

15.5节练习:

#include <iostream>
#include <cmath>//15.21 15.22
class Graph{
public :Graph()=default;Graph(double x):r(x){}virtual double get_area()=0;virtual double get_value()=0;
protected:double r;const double Pi=3.1415926;
};class Grid:public Graph{
public :Grid()=default;Grid(double x):Graph(x){}double get_area(){return r*r;}double get_value(){return 0.0;}
};
class Circle:public Graph{
public :Circle()=default;Circle(double x):Graph(x){}double get_area(){return Pi*r*r;}double get_value(){return 0.0;}
};class Ball:public Graph{
public :Ball()=default;Ball(double x):Graph(x){}double get_area(){return 4.0*Pi*r*r;}double get_value(){return 4.0*Pi*r*r*r/3.0;}
};class Cone:public Graph{
public :Cone()=default;Cone(double x,double y):Graph(x),height(y){}double get_area(){return Pi*r*r+Pi*r*sqrt(height*height+r*r);}double get_value(){return Pi*height*r*r/3.0;}
protected:double height;
};
int main()
{Grid g(2.0);Circle ci(2.0);Ball b(2.0);Cone co(2.0,3.0);std::cout<<"Grid : "<<g.get_area()<<" m^2 "<<g.get_value()<<" m^3 "<<std::endl;std::cout<<"Cirle : "<<ci.get_area()<<" m^2 "<<ci.get_value()<<" m^3 "<<std::endl;std::cout<<"Ball : "<<b.get_area()<<" m^2 "<<b.get_value()<<" m^3 "<<std::endl;std::cout<<"Cone : "<<co.get_area()<<" m^2 "<<co.get_value()<<" m^3 "<<std::endl;return 0;
}

15.7.3节练习:

#include <iostream>//15.26
class Quote{
public :Quote()=default;Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){std::cout<<"Quote construct "<<std::endl;}Quote(const Quote &qu){this->bookNo=qu.bookNo;this->price=qu.price;std::cout<<"Quote copy "<<std::endl;}std::string isbn()const {return bookNo;}virtual ~Quote(){std::cout<<"Quote delete"<<std::endl;}
private:std::string bookNo;
protected:double price=0.0;
};class Bulk_quote:public Quote{
public :Bulk_quote()=default;Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):Quote(book,sales_price),min_num(num),discount(disc){std::cout<<"Bulk_quote construct "<<std::endl;};Bulk_quote(const Bulk_quote &bkq):Quote(bkq){this->min_num=bkq.min_num;this->discount=bkq.discount;std::cout<<"Bulk_quote copy "<<std::endl;}virtual ~Bulk_quote(){std::cout<<"Bulk_quote delete "<<std::endl;}
private:std::size_t min_num;double discount;
};int main()
{Bulk_quote b("math",20,5,0.5);Bulk_quote bb(b);return 0;
}/* 首位两行为b调用构造函数及析构函数, 中间四行为bb调用拷贝函数及析构函数
Quote construct
Bulk_quote constructQuote copy
Bulk_quote copy
Bulk_quote delete
Quote deleteBulk_quote delete
Quote delete
*/

15.8节练习:

#include <iostream>
#include <cstdio>
#include <vector>
#include <memory>//15.28 15.29
class Quote{
public :Quote()=default;Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}std::string isbn()const {return bookNo;}virtual double net_price(std::size_t n) const {return n*price;}friend double print_total(std::ostream&,const Quote&,size_t );
private:std::string bookNo;
protected:double price=0.0;
};class Bulk_quote:public Quote{
public :Bulk_quote()=default;Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):Quote(book,sales_price),min_num(num),discount(disc){};double net_price(std::size_t n) const{if(n>=min_num) return n*price*discount;else return n*price;}
private:std::size_t min_num;double discount;
};
double print_total(std::ostream &os,const Quote &item,size_t n){double ret=item.net_price(n);os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;return ret;
}int main()
{std::vector<Quote > vec1;vec1.push_back(Bulk_quote("高数",20,8,0.5));//只是把其中Quote的部分拷贝给vec1了vec1.push_back(Bulk_quote("高数",20,5,0.5));double sum1=0.0;for(auto x:vec1){sum1+=print_total(std::cout,x,7);}std::cout<<"total_price:"<<sum1<<std::endl;std::vector<std::shared_ptr<Quote> > vec2;vec2.push_back(std::make_shared<Bulk_quote>("高数",20,8,0.5)); //指针动态绑定vec2.push_back(std::make_shared<Bulk_quote>("高数",20,5,0.5));double sum2=0.0;for(auto x:vec2){sum2+=print_total(std::cout,*x,7);}std::cout<<"total_price:"<<sum2<<std::endl;return 0;
}

15.8.1节练习:

#include <iostream>
#include <memory>
#include <set>//15.30
class Quote{
public :Quote()=default;Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){}std::string isbn()const {return bookNo;}virtual double net_price(std::size_t n) const {return n*price;}friend double print_total(std::ostream&,const Quote&,size_t );// virtual Quote *clone()const &{return new Quote(*this);} 编译器不支持
private:std::string bookNo;
protected:double price=0.0;
};class Bulk_quote:public Quote{
public :Bulk_quote()=default;Bulk_quote(const std::string &book,double sales_price,std::size_t num,double disc):Quote(book,sales_price),min_num(num),discount(disc){};//Bulk_quote *clone()const &{return new Bulk_quote(*this);}double net_price(std::size_t n) const{if(n>=min_num) return n*price*discount;else return n*price;}
private:std::size_t min_num;double discount;
};double print_total(std::ostream &os,const Quote &item,size_t n){double ret=item.net_price(n);os<<"isbn: "<<item.isbn()<<" sold :"<<n<<" total due: "<<ret<<std::endl;return ret;
}class Basket{
public://向vector中插入新元素void add_item(std::shared_ptr<Quote> sale){ item.insert(sale); }//void add_item(const Quote &sale){//    item.insert(std::shared_ptr<Quote>(sale.clone()));//}//输出double total_receipt(std::ostream& os)const{double sum=0.0;//upper_bound(*iter) 指向下一个关键字//item.count(*iter) 计算关键字为*iter的元素个数for(auto iter=item.cbegin();iter!=item.cend();iter=item.upper_bound(*iter)){sum+=print_total(os,**iter,item.count(*iter));}os<<"Total Sale: "<<sum<<std::endl;return sum;}
private:static bool cmp(const std::shared_ptr<Quote > &lhs,const std::shared_ptr<Quote > &rhs){return lhs->isbn()<rhs->isbn();}std::multiset<std::shared_ptr<Quote>,decltype(cmp)*> item{cmp};
};
int main()
{Basket b;for(int i=1;i<=5;++i) b.add_item(std::make_shared<Bulk_quote>("高数",20,5,0.5));for(int i=1;i<=7;++i) b.add_item(std::make_shared<Bulk_quote>("线代",30,5,0.5));//for(int i=1;i<=5;++i) b.add_item(Bulk_quote("高数",20,5,0.5));//for(int i=1;i<=7;++i) b.add_item(Bulk_quote("线代",30,5,0.5));b.total_receipt(std::cout);return 0;
}

15.92~15.93节练习:

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <memory>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <iterator>class TextQuery;
class QueryResult;
using line=std::vector<std::string>::size_type;
//文件查询类,存错整个文件内容 以及每个单词出现的行数   定义查询函数返回一个查询结果类
class TextQuery{
public ://构造函数 获取一个文件输入对象 构造 sign p_textTextQuery(std::ifstream& in):p_text(new std::vector<std::string >){std::string senten;  //读取每行的句子while(getline(in,senten)){p_text->push_back(senten);auto len=p_text->size();    //对应行号 即从1开始std::stringstream word_in(senten);std::string word;while(word_in>>word){auto isok=sign.find(word);//若该单词还为出现过,申请新的空间if(isok==sign.cend()) sign[word].reset(new std::set<line>);sign[word]->insert(len);}}}//该函数的定义必须在QueryResult 完整定义后定义,这里只做声明QueryResult query(const std::string &s)const ;
private :std::shared_ptr<std::vector<std::string > > p_text;  //存内容std::map<std::string,std::shared_ptr<std::set<line> > > sign; //存每个单词所在行位置数
};//查询结果类 包括查询的单词 以及该单词所在的所有行数 单词所在行的句子(即必须获取所有内容)
class QueryResult{
private:std::string word;   //查询的单词std::shared_ptr<std::set<line> > p_line; //该单词的行号std::shared_ptr<std::vector<std::string> >p_text; //存句子
public ://print要使用里面的成员friend std::ostream& print(std::ostream& out,const QueryResult& qr);QueryResult(std::string s,std::shared_ptr<std::set<line> > pl,std::shared_ptr<std::vector<std::string> > pv):word(s),p_line(pl),p_text(pv){}std::set<line >::iterator begin(){   //beginreturn p_line->begin();}std::set<line >::iterator end(){   //endreturn p_line->end();}std::shared_ptr<std::vector<std::string> > get_file(){ //get_filereturn p_text;}
};
QueryResult TextQuery::query(const std::string &s)const{std::shared_ptr<std::set<line> > null_ptr(new std::set<line> );auto isok=sign.find(s);//若未找到,返回第二个参数为新申请的初始化的空间if(isok==sign.cend()) return QueryResult(s,null_ptr,p_text);else return QueryResult(s,isok->second,p_text);
}
std::ostream& print(std::ostream& out,const QueryResult &qr){out<<qr.word<<" : "<<std::endl;for(auto x:*qr.p_line) out<<"(line "<<x<<" ): "<<qr.p_text->at(x-1)<<std::endl;return out;
}class Query_base{friend class Query;  //Query使用eval() rep()函数
protected :virtual ~Query_base()=default;
private:virtual QueryResult eval(const TextQuery&)const =0; //返回与之匹配的QueryResultvirtual std::string rep()const =0;                 //返回要查询的string
};
class Query{friend Query operator~(const Query &);friend Query operator|(const Query&,const Query&);friend Query operator&(const Query&,const Query&);
public :Query(const std::string&s=""); //当Query q时,自动赋值一个""给rep( 初始值默认初始化)QueryResult eval(const TextQuery &t)const {return q->eval(t);}//Query_base::eval()std::string rep()const {return q->rep();} //Query_base::rep()
private:Query(std::shared_ptr<Query_base> query):q(query){} //构造函数,接受一个Query_base指针std::shared_ptr<Query_base> q;  //通过该指针实现多态
};class WordQuery:public Query_base{ //直接调用TextQuery的query函数即可friend class Query;WordQuery(const std::string &s):query_word(s){}QueryResult eval(const TextQuery &t)const {return t.query(query_word);}std::string rep()const {return query_word;}std::string query_word;
//    Query::Query(const std::string &s):q(new WordQuery(s)){}
};
//Query的构造函数,接受一个string 把一个WordQuery(s)赋给Query:q
inline Query::Query(const std::string &s):q(new WordQuery(s)){}
class NotQuery:public Query_base{friend Query operator~(const Query &);NotQuery(const Query &q):query(q){} //构造函数 获取一个Query参数std::string rep()const {return "~("+query.rep()+")";}QueryResult eval(const TextQuery&) const ;Query query;
};
//重载运算符,返回一个指向NotQuery类型的指针 绑定到Query
inline Query operator~(const Query &operand){return std::shared_ptr<Query_base>(new NotQuery(operand));
}class BinaryQuery:public Query_base{
protected://构造函数获得左右操作对象 及操作方法BinaryQuery(const Query &l,const Query &r,std::string s):lhs(l),rhs(r),opSym(s){}std::string rep()const{ return "("+lhs.rep()+" "+opSym+" "+rhs.rep()+")";}Query lhs,rhs; //两个运算对象std::string opSym; //运算符
};class AndQuery:public BinaryQuery{friend Query operator&(const Query&,const Query);
public :AndQuery(const Query &left,const Query &right):BinaryQuery(left,right,"&"){}QueryResult eval(const TextQuery&)const;
};
//重载运算符返回一个指向 AndQuery类型的指针 绑定到Query
inline Query operator&(const Query &lhs,const Query &rhs){return std::shared_ptr<Query_base>(new AndQuery(lhs,rhs));
}
class OrQuery:public BinaryQuery{friend Query operator|(const Query &,const Query&);
public :OrQuery(const Query &left,const Query &right):BinaryQuery(left,right,"|"){}QueryResult eval(const TextQuery&)const;
};
//重载运算符返回一个指向 OrQuery类型的指针 绑定到Query
inline Query operator|(const Query &lhs,const Query &rhs){return std::shared_ptr<Query_base>(new OrQuery(lhs,rhs));
}
//重载输出运算符,输出Query指向的rep(),可注释
std::ostream & operator<<(std::ostream &os,const Query &query){return os<<query.rep();}//把两个Query 的QueryResult合并,即两向一个set 插入两个对象的信息
QueryResult OrQuery::eval(const TextQuery& text)const {auto right=rhs.eval(text),left=lhs.eval(text);auto ret_lines=std::make_shared<std::set<line> >(left.begin(),left.end());ret_lines->insert(right.begin(),right.end());return QueryResult(rep(),ret_lines,left.get_file());
}
//调用函数 set_intersection(beg1,end1,beg2,end2,dest)函数实现
QueryResult AndQuery::eval(const TextQuery& text)const{auto left=lhs.eval(text),right=rhs.eval(text);auto ret_lines=std::make_shared<std::set<line> >();set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(*ret_lines,ret_lines->begin()));return QueryResult(rep(),ret_lines,left.get_file());
}QueryResult NotQuery::eval(const TextQuery&text)const {auto result=query.eval(text);  //result相当于一个WordQuery的结果auto ret_lines=std::make_shared<std::set<line> >(); //新建一个 *setauto beg=result.begin(),end=result.end();auto sz=result.get_file()->size();//查询内容的总行数//for(auto &x:result) std::cout<<x<<std::endl;//std::cout<<" sz :"<<sz<<std::endl;for(size_t n=1;n!=sz;++n){ //取内容中不在result,p_line中的行数放入新*set,注意从第一行开始if(beg==end || *beg!=n) ret_lines->insert(n);else if(beg!=end)++beg;}return QueryResult(rep(),ret_lines,result.get_file());
}
void runQueries(std::ifstream &infile){TextQuery tq(infile);while(true){std::cout<<"enter word to look for, or q to quit: ";std::string s;if(!(std::cin>>s) || s=="q") break;print(std::cout,tq.query(s))<<std::endl;}
}int main()
{std::ifstream infile("in.txt");TextQuery tq(infile);Query q1("i"),q2,q3=q1|q2,q4=~q1;print(std::cout,q4.eval(tq));return 0;
}/*
in.txt:
i don't think so
why i can't do it
just for her ?
i love her and i want stay with her forever
can i success ?
*/

16.1.1节练习:

#include <iostream>
#include <cstring>
#include <vector>
#include <list>
#include <algorithm>//16.2
template <typename T> int  compare(const T& a,const T& b){if(a>b) return 1;else if(a<b) return -1;return 0;
}
void fun2(){std::cout<<compare(123,12)<<std::endl;std::cout<<compare(12.12,12.13)<<std::endl;std::cout<<compare((std::string)"woqu",(std::string)"shabi")<<std::endl;std::vector<int > v1={1,2,3,4},v2={2,3,4};std::cout<<compare(v1,v2)<<std::endl;
}//16.4
template <typename T1,typename T2> T1 find1(T1 beg,T1 end,const T2& temp){while(beg!=end)if(*beg==temp) return beg;else ++beg;return end;
}
void fun4(){std::vector<int > a={1,3,4,5};auto iter=find1(a.begin(),a.end(),3);std::cout<<*iter<<std::endl;std::list<std::string > ls={"wo","qu","dou","bi"};auto iter2=find1(ls.begin(),ls.end(),"qu");std::cout<<*iter2<<std::endl;
}//16.5  这个很神奇
template <typename T,unsigned N> void print(const T (&p)[N]){for(int i=0;i<N;++i)std::cout<<p[i]<<" ";std::cout<<std::endl;
}
void fun5(){int a[]={1,3,4,5,7};char s[]="woqunimeide";print(a);print(s);
}//16.6
template <typename T,unsigned N> T* begin(T (&p)[N]){if(N>1) return p;else return NULL;
}
template <typename T,unsigned N> T* end(T (&p)[N]){if(N>1)return p+N;else return NULL;
}
void fun6(){int num[]={1,2,3,4,5};char s[]="woqufule";std::for_each(begin(num),end(num),[](const int &x){std::cout<<x<<" ";});//相当于for(auto it=begin(num);it!=end(num);+it) std::cout<<*it<<" ";std::cout<<std::endl;std::for_each(begin(s),end(s),[](const char &x){std::cout<<x<<" ";});std::cout<<std::endl;
}//16.7
template <typename T,unsigned N> constexpr unsigned size_array(T (&p)[N]){return N;
}
void fun7(){int num[]={1,2,3,4};std::cout<<size_array(num);
}
int main()
{//fun2(); //16.2//fun4(); //16.4//fun5();  //16.5//fun6();   //16.6//fun7(); //16.7return 0;
}

16.1.2节练习:

#include <iostream>
#include <vector>
#include <initializer_list>
#include <memory>
#include <stdexcept>//16.12
template <typename T> class BlobPtr;
template <typename T> class Blob{friend BlobPtr<T> ;
public:typedef typename std::vector<T>::size_type  size_type;Blob():data(std::make_shared<std::vector<T> >()){}Blob(std::initializer_list<T> lis):data(std::make_shared<std::vector<T> >(lis)){}size_type size()const {return data->size();}void push_back(const T &s){data->push_back(s);}void pop_back(){check(0,"pop on empty Blob");data->pop_back();}T &front(){check(0,"front on empty Blob");data->front();}T &back(){check(0,"back on empty Blob");return data->back();}T &operator[](size_type t);
private:std::shared_ptr<std::vector<T> > data; // emoryvoid check(size_type i,const std::string &s)const {if(data->size()<=i) throw std::out_of_range(s); // stdexcept}
};
template <typename T>
T &Blob<T>::operator[](size_type t){check(t,"subscript out of range");return (*data)[t];
}template <typename T> class BlobPtr{
public :BlobPtr():curr(0){}BlobPtr(Blob<T> &a,size_t sz=0):wptr(a.data),curr(sz){}T &operator*()const{auto p=check(curr,"derefence past end");return (*p)[curr];}BlobPtr& operator++(){BlobPtr ret=*this;curr++;// ++*this;return ret;}BlobPtr& operator--(){BlobPtr ret=*this;curr--;// --*this;return ret;}
private:std::shared_ptr<std::vector<T> > check(std::size_t t,const std::string &msg)const {auto ret=wptr.lock();if(!ret) throw std::runtime_error("unbound BlobPtr");else if(t>=ret->size())throw std::out_of_range(msg);return ret;}std::weak_ptr<std::vector<T> > wptr;std::size_t curr;
};int main()
{
//16.12Blob<std::string> b1={"a","an","the"};for(auto i=0;i<b1.size();++i) std::cout<<b1[i]<<" ";std::cout<<std::endl;BlobPtr<std::string> pb(b1);for(int i=0;i<b1.size();++i,++pb)std::cout<<*pb<<" ";return 0;
}

16.1.2节练习:

#include <iostream>
#include <stdexcept>
//16.14 16.15
template <unsigned H,unsigned W> class Screen{typedef std::string::size_type pos;
public:Screen()=default;Screen(char c):contents(H*W,c){}char get()const { return contents[cursor];} //取当前焦点的值Screen &move(pos r,pos c){  //移动焦点if(r<1) throw std::out_of_range("out of screen");cursor =(r-1)*width +c;return *this;}Screen &operator<<(const char &c){  //输出当前焦点的值contents[cursor] =c;return *this;}Screen &operator>>(char &c){    //输入当前焦点的值c=contents[cursor];return *this;}friend std::ostream &operator<<(std::ostream &os,const Screen<H,W> &c ){ //输出屏幕for(int i=0;i<c.height;++i)os<<c.contents.substr(i*W,W)<<std::endl;return os;}private:pos cursor=0;           //焦点pos height=H,width=W;   //宽高std::string contents;  //一个string 存整个屏幕
};
int main()
{Screen<10,10> src('x');src.move(5,5);src<<'c';std::cout<<src;return 0;
}

16.1.3节练习:

#include <iostream>
#include <vector>
#include <list>
#include <set>//16.19
template <typename T> void print(T& pack){for(auto &x:pack) std::cout<<x<<" ";std::cout<<std::endl;
}
//16.20
template <typename T> void print2(T& pack){for(auto it=pack.begin();it!=pack.end();++it) std::cout<<*it<<" ";std::cout<<std::endl;
}
int main()
{std::vector<int > vec={1,2,3,4,5};print(vec);print2(vec);std::list<char > li={'w','o','q','u'};print(li);print2(li);std::set<int > st={6,7,8};print(st);print2(st);return 0;
}

16.1.4节练习:

#include <iostream>
//16.21
class DebugDelete{
public :DebugDelete(std::ostream &s = std::cerr):os(s){} //构造函数template <typename T> void operator()(T *p)const{ //重载()运算符os<<"deleteing unique_ptr"<<std::endl;delete p;}
private:std::ostream &os;
};
int main()
{DebugDelete del;int *p= new int(3);del(p);std::cout<<*p;return 0;
}

16.1.4节练习:

#include <iostream>
#include <vector>
#include <memory>
#include <stdexcept>template <typename T> class Blob{
public:typedef typename std::vector<T>::size_type  size_type;Blob():data(std::make_shared<std::vector<T> >()){}Blob(std::initializer_list<T> lis):data(std::make_shared<std::vector<T> >(lis)){}size_type size()const {return data->size();}void push_back(const T &s){data->push_back(s);}void pop_back(){check(0,"pop on empty Blob");data->pop_back();}T &front(){check(0,"front on empty Blob");data->front();}T &back(){check(0,"back on empty Blob");return data->back();}T &operator[](size_type t);//16.24Blob(typename std::vector<T>::iterator b,typename std::vector<T>::iterator e){data=std::make_shared<std::vector<T> >(b,e);}
private:std::shared_ptr<std::vector<T> > data; // emoryvoid check(size_type i,const std::string &s)const {if(data->size()<=i) throw std::out_of_range(s); // stdexcept}
};
int main()
{std::vector<int > v={1,2,3};Blob<int> b(v.begin(),v.end());std::cout<<b.back();return 0;
}

未完待续。。。

C++ Primer 第五版 部分课后题答案相关推荐

  1. 数据库(第五版)课后习题答案

    仅供参考,有任何问题概不负责,请同学们谨慎参考!!! 数据库系统概论第五版 答案 第1章 绪论 1 .试述数据.数据库.数据库系统.数据库管理系统的概念. 答:( l )数据( Data ) :描述事 ...

  2. 数字逻辑与数字系统(第五版)课后习题答案

    (519条消息) 数字逻辑与数字电路指导(课后题)_Half-up的博客-CSDN博客 转载,仅供学习方便查阅

  3. 云计算导论(第2版)课后题答案

    云计算课后习题答案 第1章 1.6 习题 1.美国国家标准与技术研究院(NIST)是如何定义云计算的? 答案:云计算是一种按使用量付费的模式,这种模式提供可用的.便捷的.按需的网络访问, 进入可配置的 ...

  4. 现代操作系统(原书第四版)课后题答案 —— 第四章 文件系统

    1. 给出文件 /etc/passwd 的五种不同的路径名.(提示:考虑目录项 "." 和 "-") /etc/-/etc/passwd /etc/-/etc/ ...

  5. 现代操作系统(原书第四版)课后题答案 —— 第三章 内存管理

    1. IBM 360 有一个设计,为了对 2KB 大小的块进行加锁,会对每个块分配一个 4bit 的秘钥,这个秘钥会存在 PSW 中,每次内存引用时,CPU都会进行秘钥比较.但该设计有诸多缺陷,除了描 ...

  6. 网络安全——技术与实践(第3版)课后题答案

    第二章:计算机网络基础 1.主机的IPv4的地址长度为32位,主机的MAC地址长度为48位. 2.端口号的长度是16位. 4.路由器至少拥有2个IP地址. 5.TCP是有连接的,提供可靠传输的协议. ...

  7. C++Primer第五版——习题答案+详解(完整版)

     C++Primer第五版--习题答案详解 新手入门必看的书.知识是一个系统化并且相互关联的体系,零散的东西每天收获如果不形成自己的体系的话,那将是毫无意义的,所以我觉得有必要将这本书先啃一遍,消化其 ...

  8. C++Primer第五版——习题答案详解

     C++Primer第五版--习题答案详解 新手入门必看的书.知识是一个系统化并且相互关联的体系,零散的东西每天收获如果不形成自己的体系的话,那将是毫无意义的,所以我觉得有必要将这本书先啃一遍,消化其 ...

  9. C++ primer 第五版习题答案, Stanley B. Lippman( 斯坦利 李普曼)(持续更新中)

    最新重新看c++ primer 5 第五版本,看到网上很多人在找答案,而这本书是2013年9月份的样子出来的,网上肯定是没有标准答案的,而很多人冒天下之大不韪用c plus plus的答案来来骗取分数 ...

最新文章

  1. this is incompatible with sql_mode=only_full_group_by
  2. python发送微信消息_用python批量发送微信消息
  3. hdu3234 带权并查集(XOR)
  4. 设置同一Label内涵不同颜色字体
  5. 云炬随笔20211002
  6. 焊接机器人应用现状及发展趋势
  7. 解决:Request header field Content-Type is not allowed by Access-Control-Allow-Headers
  8. 手机看直播时卡屏幕显示无法连接服务器,看直播不再卡!教你几招提升网速方法...
  9. AI 领域一大进展:“分布式”和“深度学习”真正深度融合
  10. 嵌入式Linux系统uart串口编程详解及实例分析
  11. 关于雅虎邮箱的Foxmail,outlook设置。
  12. HTML基础之表单提交
  13. 记录下在线扩容服务器遇到的问题 NOCHANGE: partition 1 is size 419428319. it cannot be grown
  14. 设置PHP的环境变量,区分PHP的测试环境和正式环境【php】
  15. 【Machine Learning】使用随机森林进行特征选择
  16. php twig中文手册,使用技巧 · Twig 中文文档 · 看云
  17. 真正的爷们该做的事!
  18. PowerBI-日期和时间函数-EOMONTH
  19. VI编辑器 Search it Bottom, Continuing at Top
  20. 阿里巴巴开发手册解析个人笔记(六)工程结构

热门文章

  1. 【Error】远程连接凭据不工作
  2. 计算机小学期实践报告,北科大一小学期暑期计算机实践实习报告.pdf
  3. 《大学计算机》上机考试系统操作指南~~
  4. 以下哪些Linux命令可以重启计算机的是,linux重启命令
  5. 合理期货回撤率(期货回撤得分)
  6. github信息安全开源课
  7. 联想服务器接显示器一直黑屏,终于发现联想液晶显示器闪烁一下后黑屏是什么原因...
  8. 编程基础:计算机相关知识
  9. 部分业务系统英文缩写及释义
  10. 最火手游《纪念碑谷》,设计灵感来自于他…… (转发自微信公众号文艺sao客)...