第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();
}
#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;
}
#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>
<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
#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
#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