读书笔记之: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

 

posted @ 2012-08-09 12:33  Mr.Rico  阅读(413)  评论(0编辑  收藏  举报