读书笔记之:Accelerated C++ 中文版[+]

第1 章 使用字符串

第7章 使用关联容器

下面一个交叉引用表达代码,其中包括了getword函数

View Code
#include <iostream>
#include <vector>
#include < string>
#include <map>
using  namespace std;

vector< string> getwords( const  string& str)
{
    vector< string> ret;
     static  string delim= "  \\/,.;:!~*`\'\"\t\b\n#<>(){}[]]&=-+ ";
     string word;
    size_t pos,pos2;
    size_t len=str.size();
    pos=- 1;
     bool flag= true;
     while(flag){
        pos=str.find_first_not_of(delim,pos+ 1);
         if(pos== string::npos)
             break;
        pos2=str.find_first_of(delim,pos+ 1);
         if(pos2== string::npos)
        {
            pos2=len- 1;
            flag= false;
        }
        word=str.substr(pos,pos2-pos+ 1);
        ret.push_back(word);
//         cout<<word<<' ';
        pos=pos2;
    }
//     cout<<endl;
     return ret;
}
map< string, vector< int> >
    xref(istream&  in,
         vector< string> find_words( const  string&) = getwords)
{
     string line;
     int line_number =  0;
    map< string, vector< int> > ret;

     //  read the next line
     while (getline( in, line)) {
        ++line_number;

         //  break the input line into words
        vector< string> words = find_words(line);

         //  remember that each word occurs on the current line
         for (vector< string>::const_iterator it = words.begin();
             it != words.end(); ++it)
            ret[*it].push_back(line_number);
    }
     return ret;
}
int test1(){
     string line;
     while(getline(cin,line)){
        getwords(line);
    }
     return  0;
}

int test2()
{
     //  call `xref' using `split' by default
    map< string, vector< int> > ret = xref(cin);

     //  write the results
     for (map< string, vector< int> >::const_iterator it = ret.begin();
         it != ret.end(); ++it) {
         //  write the word
        cout << it->first <<  "  occurs on line(s):  ";

         //  followed by one or more line numbers
        vector< int>::const_iterator line_it = it->second.begin();
        cout << *line_it;     //  write the first line number

        ++line_it;
         //  write the rest of the line numbers, if any
         while (line_it != it->second.end()) {
            cout <<  " " << *line_it;
            ++line_it;
        }
         //  write a new line to separate each word from the next
        cout << endl;
    }

     return  0;
}

int main(){
    test2();
}

代码如下:

View Code
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <map>
#include <stdexcept>
#include < string>
#include <vector>

#include <time.h>

using std::istream;            using std::cin;
using std::copy;               using std::cout;
using std::endl;               using std::find;
using std::getline;            using std::logic_error;
using std::map;                using std:: string;
using std::vector;             using std::domain_error;
using std::rand;

typedef vector< string> Rule;
typedef vector<Rule> Rule_collection;
typedef map< string, Rule_collection> Grammar;

vector< string> getwords( const  string& str)
{
    vector< string> ret;
     static  string delim= "  \\/,.;:!~*`\'\"\t\b\n#(){}[]&=-+ ";
     string word;
    size_t pos,pos2;
    size_t len=str.size();
    pos=- 1;
     bool flag= true;
     while(flag){
        pos=str.find_first_not_of(delim,pos+ 1);
         if(pos== string::npos)
             break;
        pos2=str.find_first_of(delim,pos+ 1);
         if(pos2== string::npos)
        {
            pos2=len- 1;
            flag= false;
        }
        word=str.substr(pos,pos2-pos+ 1);
        ret.push_back(word);
        cout<<word<< '   ';
        pos=pos2;
    }
    cout<<endl;
     return ret;
}
//  read a grammar from a given input stream
Grammar read_grammar(istream&  in)
{
    Grammar ret;
     string line;

     //  read the input
     while (getline( in, line)) {

         //  `split' the input into words
        vector< string> entry = getwords(line);

         if (!entry.empty())
             //  use the category to store the associated rule
            ret[entry[ 0]].push_back(
                Rule(entry.begin() +  1, entry.end()));
    }
     return ret;
}

void gen_aux( const Grammar&,  const  string&, vector< string>&);

int nrand( int);

vector< string> gen_sentence( const Grammar& g)
{
    vector< string> ret;
    gen_aux(g,  " <sentence> ", ret);
     return ret;
}

bool bracketed( const  string& s)
{
     return s.size() >  1 && s[ 0] ==  ' < ' && s[s.size() -  1] ==  ' > ';
}

void
gen_aux( const Grammar& g,  const  string& word, vector< string>& ret)
{

     if (!bracketed(word)) {
        ret.push_back(word);
    }  else {
         //  locate the rule that corresponds to `word'
        Grammar::const_iterator it = g.find(word);
         if (it == g.end())
             throw logic_error( " empty rule ");

         //  fetch the set of possible rules
         const Rule_collection& c = it->second;

         //  from which we select one at random
         const Rule& r = c[nrand(c.size())];

         //  recursively expand the selected rule
         for (Rule::const_iterator i = r.begin(); i != r.end(); ++i)
            gen_aux(g, *i, ret);
    }
}

int main()
{
     //  generate the sentence
    vector< string> sentence = gen_sentence(read_grammar(cin));

     //  write the first word, if any
    vector< string>::const_iterator it = sentence.begin();
     if (!sentence.empty()) {
        cout << *it;
        ++it;
    }

     //  write the rest of the words, each preceded by a space
     while (it != sentence.end()) {
        cout <<  "   " << *it;
        ++it;
    }

    cout << endl;
     return  0;
}

//  return a random integer in the range `[0,' `n)'
int nrand( int n)
{
     if (n <=  0 || n > RAND_MAX)
         throw domain_error( " Argument to nrand is out of range ");

     const  int bucket_size = RAND_MAX / n;
     int r;

     do r = rand() / bucket_size;
     while (r >= n);

     return r;
}

输入如下:

<noun> cat
<noun> dog
<noun> table
<noun_phrase> <adjective> <noun_phrase>
<noun_phrase> <noun>
<adjective> large
<adjective> brown
<adjective> absurd
<verb> jumps
<verb> sits
<location> on the stairs
<location> under the sky
<location> wherever it wants
<sentence> the <noun_phrase> <verb> <location>

 

第14章 句柄

代码如下:

Handle.h

View Code
#ifndef GUARD_Handle_h
#define GUARD_Handle_h

template < class T>  class Handle {
public:
    Handle(): p( 0) { }
    Handle( const Handle& s): p( 0) {  if (s.p) p = s.p->clone(); }
    Handle&  operator=( const Handle&);
    ~Handle() { delete p; }

    Handle(T* t): p(t) { }

     operator  bool()  const {  return p; }
    T&  operator*()  const;
    T*  operator->()  const;

private:
    T* p;
};

#include <stdexcept>

using std::runtime_error;

template < class T>
Handle<T>& Handle<T>:: operator=( const Handle& rhs)
{
     if (&rhs !=  this) {
        delete p;
        p = rhs.p ? rhs.p->clone() :  0;
    }
     return * this;
}

template < class T>
T& Handle<T>:: operator*()  const
{
     if (p)     
         return *p;
     throw runtime_error( " unbound Handle ");
}

template < class T>
T* Handle<T>:: operator->()  const
{
     if (p)
         return p;
     throw runtime_error( " unbound Handle ");
}

#endif

 


代码如下:

Ref_handle.h

View Code
#ifndef Ref_handle_h
#define Ref_handle_h

#include <cstddef>
#include <stdexcept>

template < class T>  class Ref_handle {
public:
     //  manage reference count as well as pointer
    Ref_handle(): p( 0), refptr( new size_t( 1)) { }
    Ref_handle(T* t):  p(t), refptr( new size_t( 1)) { }
    Ref_handle( const Ref_handle& h): p(h.p), refptr(h.refptr) {
        ++*refptr;
    }

    Ref_handle&  operator=( const Ref_handle&);
    ~Ref_handle();

     //  as before
     operator  bool()  const {  return p; }
    T&  operator*()  const {
         if (p)
             return *p;
         throw std::runtime_error( " unbound Ref_handle ");
    }
    T*  operator->()  const {
         if (p)
             return p;
         throw std::runtime_error( " unbound Ref_handle ");
    }

private:
    T* p;
    std::size_t* refptr;       //  added
};

template < class T>
Ref_handle<T>& Ref_handle<T>:: operator=( const Ref_handle& rhs)
{
    ++*rhs.refptr;
     //  free the left-hand side, destroying pointers if appropriate
     if (--*refptr ==  0) {
        delete refptr;
        delete p;
    }

     //  copy in values from the right-hand side
    refptr = rhs.refptr;
    p = rhs.p;
     return * this;
}

template < class T> Ref_handle<T>::~Ref_handle()
{
     if (--*refptr ==  0) {
        delete refptr;
        delete p;
    }
}

#endif

 

转载于:https://www.cnblogs.com/xkfz007/archive/2012/08/09/2630058.html

本书全面介绍了C++语言。作为一本入门书(Primer),它以教程的形式对C++语言进行清晰的讲解,并辅以丰富的示例和各种学习辅助手段。与大多数入门教程不同,本书对C++语言本身进行了详尽的描述,并特别着重介绍了目前通行的、行之有效的程序设计技巧。   无数程序员曾使用本书的前几个版本学习C++,在此期间C++也逐渐发展成熟。这些年来,C++语言的发展方向以及C++程序员的关注点,已经从以往注重运行时的效率,转到千方百计地提高程序员的编程效率上。随着标准库的广泛可用,我们现在能够比以往任何时候更高效地学习和使用C++。本书这一版本充分体现了这一点。第4版的改动为了体现现代C++编程风格,我们重新组织并重写了本书。书中不再强调低层编程技术,而把中心转向标准库的使用。书中很早就开始介绍标准库,示例也已经重新改写,充分利用了标准库设施。我们也对语言主题叙述的先后次序进行了重新编排,使讲解更加流畅。除重新组织内容外,为了便于读者理解,我们还增加了几个新的环节。每一章都新增了“小结”和“术语”,概括本章要点。读者可以利用这些部分进行自我检查;如果发现还有不理解的概念,可以重新学习该章中的相关部分。书中还加入了下述几种学习辅助手段:重要术语用黑体表示,我们认为读者已经熟悉的重要术语则用楷体表示。这些术语都会出现在章后的“术语”部分。书中用特殊版式突出标注的文字,是为了向读者提醒语言的重要特征,警示常见的错误,标明良好的编程实践,列出通用的使用技巧。希望这些标注可以帮助读者更快地消化重要概念,避免犯常见错误。为了更易于理解各种特征或概念间的关系,书中大量使用了前后交叉引用。.. 对于某些重要概念和C++新手最头疼的问题,我们进行了额外的讨论和解释。这部分也以特殊版式标出。学习任何程序设计语言都需要编写程序。因此,本书提供了大量的示例。所有示例的源代码可从下列网址获得: http://www.awprofessional.com/cpp_primer 万变不离其宗,本书保持了前几版的特色,仍然是一部全面介绍C++的教程。我们的目标是提供一本清晰、全面、准确的指南性读物。我们通过讲解一系列示例来教授C++语言,示例除了解释语言特征外,还展示了如何善用这门语言。虽然读者不需要事先学过C语言(C++最初的基础)的知识,但我们假定读者已经掌握了一种现代结构化语言。本书结构本书介绍了C++国际标准,既涵盖语言的特征,又讲述了也是标准组成部分的丰富标准库。C++的强大很大程度上来自它支持抽象程序设计。要学会用C++高效地编程,只是掌握句法和语义是远远不够的。我们的重点,在于教会读者怎样利用C++的特性,快速地写出安全的而且性能可与C语言低层程序相媲美的程序。 C++是一种大型的编程语言,这可能会吓倒一些新手。现代C++可以看成由以下三部分组成: l 低级语言,多半继承自C。 l 更高级的语言特征,用户可以借此定义自己的数据类型,组织大规模的程序和系统。 l 标准库,使用上述高级特征提供一整套有用的数据结构和算法。多数C++教材按照下面的顺序展开:先讲低级细节,再介绍更高级的语言特征;在讲完整个语言后才开始解释标准库。结果往往使读者纠缠于低级的程序设计问题和复杂类型定义的编写等细节,而不能真正领会抽象编程的力量。就更不用说学到足够的知识去创建自己的抽象了。本版中我们独辟蹊径。一开始就讲述语言的基础知识和标准库,这样读者就可以写出比较大的有实际意义的程序来。透彻阐释了使用标准库(并且用标准库编写了各种抽象程序)的基础知识之后,我们才进入下一步,学习用C++的其他高级特征,来编写自己的抽象。第一和第二部分讨论语言的基础知识和标准库设施。其重点在于学会如何编写C++程序,如何使用标准库提供的抽象设施。大部分C++程序员需要了解本书这两部分的内容。除了讲解基础知识以外,这两部分还有另外一个重要的意图。标准库设施本身是用C++编写的抽象数据类型,定义标准库所使用的是任何C++程序员都能使用的构造类的语言特征。我们教授C++的经验说明,一开始就使用设计良好的抽象类型,读者会更容易理解如何建立自己的类型。第三到第五部分着重讨论如何编写自己的类型。第三部分介绍C++的核心,即对类的支持。类机制提供了编写自定义抽象的基础。类也是第四部分中所讨论的面向对象编程和泛型编程的基础。全书正文的最后是第五部分,我们在这一部分讨论了一些高级特征,它们在构建大型复杂系统时最为常用。致谢与前几版一样,我们要感谢Bjarne Stroustrup,他不知疲倦地从事着C++方面的工作,他与我们的深厚友情由来已久。我们还要感谢Alex Stepanov,正是他最初凭借敏锐的洞察力创造了容器和算法的概念,这些概念最终形成了标准库的核心。此外,我们要感谢C++标准委员会的所有成员,他们多年来为C++
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值