C++ Primer文本查询程序(TextQuery)功能加强版
2014-07-01 09:53
465 查看
详见书的15.9节。
面向对象的实现。
一些需要 注意的 地方:
1.#pragma once,在 TextQuery.h文件 中添加,确保其只被编译一次,避免redefinition错误
一些 细节,参照了这位大神的 代码http://blog.csdn.net/hustspy1990/article/details/7296485
先贴 代码,运行起来 似乎 还有些 问题 ,可 再修正
1.TextQuery.h
#pragma once
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <cstdlib>
using namespace std;
class TextQuery{
public:
typedef vector<string>::size_type line_no;//是一种别名,类型
void read_file(ifstream &is)
{
store_file(is);//读入并保存文件
build_map();//创建关联单词和行号的map容器
}
set<line_no> run_query(const string&) const;
string text_line(line_no) const;//行文本
line_no size() const { return lines_of_text.size(); } //新添加的函数,返回文件的大小
private:
void store_file(ifstream&);
void build_map();
vector<string> lines_of_text;//文件行存储
map<string,set<line_no>> word_map;//关联容器,单词和文本记录关联
};
2.TextQuery.cpp
#include "TextQuery.h"
using namespace std;
void TextQuery::store_file(ifstream &is)
{
string textline;
while (getline(is,textline))
lines_of_text.push_back(textline);
}
void TextQuery::build_map()//将读入的单词和行号进行关联
{
for(line_no line_num=0;line_num!=lines_of_text.size();++line_num){
istringstream line(lines_of_text[line_num]);
string word;
while(line>>word)
word_map[word].insert(line_num);
}
}
set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const//执行查询函数
{
map<string,set<line_no>>::const_iterator
loc=word_map.find(query_word);
if(loc==word_map.end())
return set<line_no>();//没有找到,返回空的set集合
else
return loc->second;//找到,当返回行
}
string TextQuery::text_line(line_no line) const//同时还需要返回行
{
if(line < lines_of_text.size())
return lines_of_text[line];
throw out_of_range("line number out of range");
}
string make_plural(size_t ctr,const string &word,const string &ending)//当计数器不为一的时候,返回单词的复数版本
{
return (ctr==1) ? word: word+ending;
}
3.QueryAll.h
/*C++ Primer文本查询程序*/
#ifndef QUERY_H
#define QUERY_H
#include "TextQuery.h"
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <cstdlib>
using namespace std;
class Query_base{//虚基类
friend class Query;
protected:
typedef TextQuery::line_no line_no;
virtual ~Query_base(){}
private:
virtual std::set<line_no> eval(const TextQuery&) const=0;//纯虚函数,该类为虚基类
virtual ostream& display(ostream& = cout) const=0;
};
class Query{//Query句柄类
friend Query operator~(const Query&);
friend Query operator|(const Query&,const Query&);
friend Query operator&(const Query&,const Query&);
public:
Query(const string&);
Query(const Query &c):q(c.q),use(c.use) {++*use;}
~Query(){decr_use();}
Query& operator=(const Query&);
std::set<TextQuery::line_no> eval(const TextQuery &t) const {return q->eval(t);}
ostream &display(ostream &os) const
{
return q->display(os);
}
private:
Query(Query_base *query):q(query),use(new size_t(1)){}
Query_base *q;
size_t *use;
void decr_use()
{
if(--*use==0){delete q; delete use;}//计数为0 ,释放资源
}
};
//Query输出操作符
inline ostream& operator<<(ostream &os,const Query &q)
{
return q.display(os);
}
class WordQuery:public Query_base{
friend class Query;
WordQuery(const string &s):query_word(s){}
set<line_no> eval(const TextQuery &t) const
{
return t.run_query(query_word);
}
ostream& display(ostream &os) const
{
return os<<query_word;
}
string query_word;
};
//NotQuery类
class NotQuery:public Query_base{
friend Query operator~(const Query &);
NotQuery(Query q):query(q){}
set<line_no> eval(const TextQuery&) const;
ostream& display(ostream &os) const
{
return os << "~(" << query << ")";
}
const Query query;
};
//BinaryQuery类
class BinaryQuery:public Query_base{
protected:
BinaryQuery(Query left,Query right,string op):
lhs(left),rhs(right),oper(op){}
ostream& display(ostream &os) const
{
return os << "(" << lhs << " " << oper << " " << rhs << ")";
}
const Query lhs,rhs;
const string oper;
};
//AndQuery类和orQuery类
class AndQuery:public BinaryQuery{
friend Query operator&(const Query&,const Query&);
AndQuery (Query left,Query right):BinaryQuery(left,right,"&"){}
set<line_no> eval(const TextQuery&) const;
};
class OrQuery:public BinaryQuery{
friend Query operator|(const Query&,const Query&);
OrQuery(Query left,Query right):BinaryQuery(left,right,"|"){}
set<line_no> eval(const TextQuery&) const;
};
//Query重载操作符
inline Query operator&(const Query &lhs,const Query &rhs)
{
return new AndQuery(lhs,rhs);
}
inline Query operator|(const Query &lhs,const Query &rhs)//操作符,内联函数
{
return new OrQuery(lhs,rhs);
}
inline Query operator ~ (const Query &oper)
{
return new NotQuery(oper);
}
inline Query::Query(const std::string& word): q(new WordQuery(word)), use(new std::size_t(1)) {}
#endif
4.QueryAll.cpp
#include "QueryAll.h"
#include <map>
#include <iostream>
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include<iterator>
using namespace std;
//OrQuery::eval
set<TextQuery::line_no> OrQuery::eval(const TextQuery& file) const
{
set<line_no> right=rhs.eval(file),
ret_lines=lhs.eval(file);
ret_lines.insert(right.begin(),right.end());
return ret_lines;
}
//AndQuery::eval
set<TextQuery::line_no> AndQuery::eval(const TextQuery& file) const
{
set<line_no> left =lhs.eval(file),
right=rhs.eval(file);
set<line_no> ret_lines;
set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(ret_lines,ret_lines.begin()));
return ret_lines;
}
//NotQUery::eval
set<TextQuery::line_no> NotQuery::eval(const TextQuery& file) const
{
set<TextQuery::line_no> has_val=query.eval(file);
set<line_no> ret_lines;
for (TextQuery::line_no n=0;n!=file.size();++n)
if(has_val.find(n)==has_val.end())
ret_lines.insert(n);
return ret_lines;
}
5.main.cpp
#include "TextQuery.h"
#include <fstream>
#include "QueryAll.h"
using namespace std;
void print_result(const set<TextQuery::line_no>& locs, const string& sought, const TextQuery& file)
{
typedef set<TextQuery::line_no> line_nums;
line_nums::size_type size = locs.size();
cout<<"\n"<<sought<<" occurs "<<size<<(size>1 ? "Times":"Time")<<endl;
line_nums::const_iterator it = locs.begin();
for(; it!=locs.end(); ++it)
cout<<(*it)+1<<"\t"<<file.text_line(*it)<<endl;
}
int main()
{
ifstream is("D:\\Users\\shiwei\\Desktop\\test.txt");
TextQuery tq;
tq.read_file(is);
Query q = Query("The") & Query("of") | Query("the");
std::set<TextQuery::line_no> locs = q.eval(tq);
//string s("((fiery & bird) | wind)");
string s("the & home");
//string s;
//cin>>s;
print_result(locs, s, tq);
while(true) {
int i;
cin>>i;
};
return 0;
}
面向对象的实现。
一些需要 注意的 地方:
1.#pragma once,在 TextQuery.h文件 中添加,确保其只被编译一次,避免redefinition错误
一些 细节,参照了这位大神的 代码http://blog.csdn.net/hustspy1990/article/details/7296485
先贴 代码,运行起来 似乎 还有些 问题 ,可 再修正
1.TextQuery.h
#pragma once
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <cstdlib>
using namespace std;
class TextQuery{
public:
typedef vector<string>::size_type line_no;//是一种别名,类型
void read_file(ifstream &is)
{
store_file(is);//读入并保存文件
build_map();//创建关联单词和行号的map容器
}
set<line_no> run_query(const string&) const;
string text_line(line_no) const;//行文本
line_no size() const { return lines_of_text.size(); } //新添加的函数,返回文件的大小
private:
void store_file(ifstream&);
void build_map();
vector<string> lines_of_text;//文件行存储
map<string,set<line_no>> word_map;//关联容器,单词和文本记录关联
};
2.TextQuery.cpp
#include "TextQuery.h"
using namespace std;
void TextQuery::store_file(ifstream &is)
{
string textline;
while (getline(is,textline))
lines_of_text.push_back(textline);
}
void TextQuery::build_map()//将读入的单词和行号进行关联
{
for(line_no line_num=0;line_num!=lines_of_text.size();++line_num){
istringstream line(lines_of_text[line_num]);
string word;
while(line>>word)
word_map[word].insert(line_num);
}
}
set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const//执行查询函数
{
map<string,set<line_no>>::const_iterator
loc=word_map.find(query_word);
if(loc==word_map.end())
return set<line_no>();//没有找到,返回空的set集合
else
return loc->second;//找到,当返回行
}
string TextQuery::text_line(line_no line) const//同时还需要返回行
{
if(line < lines_of_text.size())
return lines_of_text[line];
throw out_of_range("line number out of range");
}
string make_plural(size_t ctr,const string &word,const string &ending)//当计数器不为一的时候,返回单词的复数版本
{
return (ctr==1) ? word: word+ending;
}
3.QueryAll.h
/*C++ Primer文本查询程序*/
#ifndef QUERY_H
#define QUERY_H
#include "TextQuery.h"
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <cstdlib>
using namespace std;
class Query_base{//虚基类
friend class Query;
protected:
typedef TextQuery::line_no line_no;
virtual ~Query_base(){}
private:
virtual std::set<line_no> eval(const TextQuery&) const=0;//纯虚函数,该类为虚基类
virtual ostream& display(ostream& = cout) const=0;
};
class Query{//Query句柄类
friend Query operator~(const Query&);
friend Query operator|(const Query&,const Query&);
friend Query operator&(const Query&,const Query&);
public:
Query(const string&);
Query(const Query &c):q(c.q),use(c.use) {++*use;}
~Query(){decr_use();}
Query& operator=(const Query&);
std::set<TextQuery::line_no> eval(const TextQuery &t) const {return q->eval(t);}
ostream &display(ostream &os) const
{
return q->display(os);
}
private:
Query(Query_base *query):q(query),use(new size_t(1)){}
Query_base *q;
size_t *use;
void decr_use()
{
if(--*use==0){delete q; delete use;}//计数为0 ,释放资源
}
};
//Query输出操作符
inline ostream& operator<<(ostream &os,const Query &q)
{
return q.display(os);
}
class WordQuery:public Query_base{
friend class Query;
WordQuery(const string &s):query_word(s){}
set<line_no> eval(const TextQuery &t) const
{
return t.run_query(query_word);
}
ostream& display(ostream &os) const
{
return os<<query_word;
}
string query_word;
};
//NotQuery类
class NotQuery:public Query_base{
friend Query operator~(const Query &);
NotQuery(Query q):query(q){}
set<line_no> eval(const TextQuery&) const;
ostream& display(ostream &os) const
{
return os << "~(" << query << ")";
}
const Query query;
};
//BinaryQuery类
class BinaryQuery:public Query_base{
protected:
BinaryQuery(Query left,Query right,string op):
lhs(left),rhs(right),oper(op){}
ostream& display(ostream &os) const
{
return os << "(" << lhs << " " << oper << " " << rhs << ")";
}
const Query lhs,rhs;
const string oper;
};
//AndQuery类和orQuery类
class AndQuery:public BinaryQuery{
friend Query operator&(const Query&,const Query&);
AndQuery (Query left,Query right):BinaryQuery(left,right,"&"){}
set<line_no> eval(const TextQuery&) const;
};
class OrQuery:public BinaryQuery{
friend Query operator|(const Query&,const Query&);
OrQuery(Query left,Query right):BinaryQuery(left,right,"|"){}
set<line_no> eval(const TextQuery&) const;
};
//Query重载操作符
inline Query operator&(const Query &lhs,const Query &rhs)
{
return new AndQuery(lhs,rhs);
}
inline Query operator|(const Query &lhs,const Query &rhs)//操作符,内联函数
{
return new OrQuery(lhs,rhs);
}
inline Query operator ~ (const Query &oper)
{
return new NotQuery(oper);
}
inline Query::Query(const std::string& word): q(new WordQuery(word)), use(new std::size_t(1)) {}
#endif
4.QueryAll.cpp
#include "QueryAll.h"
#include <map>
#include <iostream>
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include<iterator>
using namespace std;
//OrQuery::eval
set<TextQuery::line_no> OrQuery::eval(const TextQuery& file) const
{
set<line_no> right=rhs.eval(file),
ret_lines=lhs.eval(file);
ret_lines.insert(right.begin(),right.end());
return ret_lines;
}
//AndQuery::eval
set<TextQuery::line_no> AndQuery::eval(const TextQuery& file) const
{
set<line_no> left =lhs.eval(file),
right=rhs.eval(file);
set<line_no> ret_lines;
set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(ret_lines,ret_lines.begin()));
return ret_lines;
}
//NotQUery::eval
set<TextQuery::line_no> NotQuery::eval(const TextQuery& file) const
{
set<TextQuery::line_no> has_val=query.eval(file);
set<line_no> ret_lines;
for (TextQuery::line_no n=0;n!=file.size();++n)
if(has_val.find(n)==has_val.end())
ret_lines.insert(n);
return ret_lines;
}
5.main.cpp
#include "TextQuery.h"
#include <fstream>
#include "QueryAll.h"
using namespace std;
void print_result(const set<TextQuery::line_no>& locs, const string& sought, const TextQuery& file)
{
typedef set<TextQuery::line_no> line_nums;
line_nums::size_type size = locs.size();
cout<<"\n"<<sought<<" occurs "<<size<<(size>1 ? "Times":"Time")<<endl;
line_nums::const_iterator it = locs.begin();
for(; it!=locs.end(); ++it)
cout<<(*it)+1<<"\t"<<file.text_line(*it)<<endl;
}
int main()
{
ifstream is("D:\\Users\\shiwei\\Desktop\\test.txt");
TextQuery tq;
tq.read_file(is);
Query q = Query("The") & Query("of") | Query("the");
std::set<TextQuery::line_no> locs = q.eval(tq);
//string s("((fiery & bird) | wind)");
string s("the & home");
//string s;
//cin>>s;
print_result(locs, s, tq);
while(true) {
int i;
cin>>i;
};
return 0;
}
相关文章推荐
- C++ Primer文本查询程序(TextQuery)的实现(2014.5.24)
- C++ primer 文本查询程序 Query
- c++ primer( 文本查询程序)
- C++ Primer 关联容器--容器的综合应用:文本查询程序
- C++ Primer 文本查询程序
- C++ Primer 第五版 文本查询程序
- c++ primer 5ed 15.9文本查询程序再探
- 【C++ Primer】文本查询程序再探
- C++ Primer 第15章例子-文本查询程序
- 《C++ Primer 5th》读书笔记4---文本查询程序
- 【C++ Primer】【学习笔记】【第十章】关联容器之:文本查询程序
- 容器的综合应用:文本查询程序(摘自C++ Primer)
- 《c++ primer》文本查询程序和邮件处理程序
- c++ primer--容器的综合应用:文本查询程序
- C++ primer 文本查询程序
- 一个简单的文本查询程序—摘至《C++ Primer》
- C++ primer 第五版 12.3文本查询程序完整版
- C++ Primer 学习笔记_38_STL实践与分析(12)--容器的综合应用:文本查询程序
- c++ primer习题10.6 文本查询程序
- C++ Primer 学习笔记_38_STL实践与分析(12)--集成的应用程序容器:文本查询程序