C++ Primer 第五版 部分课后题答案

            当时刚学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"); 最后结果是 helloxxxx

    char *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.6
    int 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 a
    std::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 b
    std::vector<int > vecc;
    vecc.reserve(10);
    //虽然分配了内存 但size()=0 vecc.begin()==vecc.end() capacity()=10
    std::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.15
    int x,y;
    std::cin>>x>>y;
    auto fun2=[x](const int y){return x+y;};
    std::cout<<fun2(y)<<std::endl;

    //10.16
    std::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.27
    std::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.29
    std::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.30
    std::istream_iterator<int > in(std::cin); //in从输入流cin中读取类型为int的值
    std::istream_iterator<int > eof2;  //输入流结束位置
    std::vector<int > vec2(in,eof2);   //输入的数据读入vec2
    sort(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.33
    fun("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.35
    std::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.36
    std::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.37
    std::vector <int > vec2={1,2,3,4,5,6,7,8,9,10}; // 取其中 3~7 的位置复制给std::list
    std::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.13
    std::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.14
    std::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.20
    std::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.23
    std::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.31
    std::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 later

test2.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; // emory
    void check(vstring::size_type i,const std::string &s)const {
        if(data->size()<=i) throw std::out_of_range(s); // stdexcept
    }
};
int main()
{
    //12.1
    StrBlob 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.6
    auto pv=new_vecint();
    for(int i=1;i<=3;++i) read_data(std::cin,pv);
    print(pv);

    //12.7
    auto 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; // memory
    void 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.20
    std::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 指针类型输出StrBlob
    while(!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.23
    char 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.24
    std::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_text
    TextQuery(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; // emory
    void 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_text
    TextQuery(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.27

class TextQuery;
class QueryResult;
using line=std::vector<std::string>::size_type;
//文件查询类,存错整个文件内容 以及每个单词出现的行数   定义查询函数返回一个查询结果类
class TextQuery{
public :
    //构造函数 获取一个文件输入对象 构造 sign p_text
    TextQuery(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(){   //begin
        return p_line->begin();
    }
    std::set<line >::iterator end(){   //end
        return p_line->end();
    }
    std::shared_ptr<std::vector<std::string> > get_file(){ //get_file
        return 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 construct

Quote copy
Bulk_quote copy
Bulk_quote delete
Quote delete

Bulk_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_text
    TextQuery(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(){   //begin
        return p_line->begin();
    }
    std::set<line >::iterator end(){   //end
        return p_line->end();
    }
    std::shared_ptr<std::vector<std::string> > get_file(){ //get_file
        return 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; //返回与之匹配的QueryResult
    virtual 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> >(); //新建一个 *set
    auto 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.7

    return 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; // emory
    void 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.12
    Blob<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.24
    Blob(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; // emory
    void 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;
}

未完待续。。。

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
C++ Primer集(第五) , 带目录完整。 --------------------------------------------------------------------------- 目录 第1章............................................................ 1 练习1.1 练 习1.25 第2 章变量和基本类型................................................. 12 练习2.1 练 习2.42 第3 章字符串、向量和数组..............................................37 练习3.1 练 习3.45 第4 章表达式......................................................... 80 练习4.1 练 习4.38 第5 章语句........................................................... 99 练习5.1 练 习5.25 第6 章函数.......................................................... 120 练习6.1 练 习6.56 m m m ...................................................................... 152 练习7.1 练 习7.58 第8 章1 0库..........................................................183 练习8.1 练 习8.14 第9 章顺序容器...................................................... 193 练习9.1 练 习9.52 第10章泛型算法..................................................... 234 练习10.1 练 习10.42 目录 ◄ v 第11章关联容器..................................................... 273 练习11.1 练 习11.38 第12章动态内存..................................................... 297 练习12.1 练 习12.33 第13章拷贝控制..................................................... 331 练习13.1 练 习13.58 第14章重载运算与类型转换............................................368 练习14.1 练 习14.53 第15章面向对象程序设计..............................................399 练习15.1 练 习15.42 第16章模板与泛型编程............................................... 424 练习16.1 练 习16.67 第17章标准库特殊设施............................................... 458 练习17.1 练 习17.39 第18章用于大型程序的工具............................................483 练习18.1 练 习18.30 第19章特殊工具与技术............................................... 502 练习19.1 练 习19.26

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值