C++primer 文本查询练习
2011-05-11 18:13
218 查看
// header file
#pragma once
#include "TextQuery.h"
#include <algorithm>
#include <iterator>
namespace StringQuery{
class QueryBase
{
friend class Query;
protected:
typedef TextQuery::line_no line_no;
virtual ~QueryBase(void){};
private:
virtual std::set<line_no> eval(const TextQuery& t) const = 0;
virtual std::ostream& display(std::ostream& os = std::cout) const = 0;
};
class Query
{
public:
friend Query operator~(const Query& );
friend Query operator|(const Query& ,const Query& );
friend Query operator&(const Query& ,const Query& );
std::set<TextQuery::line_no> eval(const TextQuery& tq) const
{
return q->eval(tq);
}
std::ostream& display(std::ostream& os) const
{
return q->display(os);
}
Query& operator=(const Query &);
public:
Query(const std::string &s);
Query(const Query& query):q(query.q),use(query.use){++*use;}
Query(QueryBase* qb):q(qb),use(new size_t(1)){}
~Query(void){decr_use();}
private:
QueryBase *q;
std::size_t *use;
inline void decr_use(void)
{
if(--*use==0)
{
delete q;
delete use;
}
}
};
inline std::ostream& operator<<(std::ostream& os,const Query &q)
{ return q.display(os); }
inline Query& Query::operator=(const Query &rhs)
{
++*rhs.use;
decr_use();
q = rhs.q;
use = rhs.use;
return *this;
}
class WordQuery:public QueryBase
{
friend class Query;
WordQuery(const std::string &s):query_word(s) { }
std::set<line_no> eval(const TextQuery &t) const
{ return t.run_query(query_word); }
std::ostream& display(std::ostream &os = std::cout) const
{ return os << query_word; }
std::string query_word;
};
inline
Query::Query(const std::string &s):q(new WordQuery(s)),
use(new std::size_t(1)) { }
class NotQuery:public QueryBase
{
friend Query operator~(const Query& query);
NotQuery(const Query& q):query(q) { }
std::set<line_no> eval(const TextQuery& file) const;
std::ostream& display(std::ostream& os = std::cout) const
{ return os << "~(" << query << ")"; }
const Query query;//implemente binding
};
class BinaryQuery:public QueryBase
{
protected:
BinaryQuery(const Query &rl,const Query &rr,const std::string &op):rhl(rl),rhr(rr),oper(op){}
std::ostream& display(std::ostream &os) const
{ return os << "~(" << rhl << "" << oper << " " << rhr << ")"; }
const Query rhl,rhr;
const std::string oper;
};
class OrQuery:public BinaryQuery
{
friend Query operator|(const Query &,const Query &);
OrQuery(const Query& rl,const Query& rr):BinaryQuery(rl,rr,"|"){}
std::set<line_no> eval(const TextQuery &file) const;
};
class AndQuery:public BinaryQuery
{
friend Query operator&(const Query &,const Query &);
AndQuery(const Query &rl,const Query &rr):BinaryQuery(rl,rr,"&"){}
std::set<line_no> eval(const TextQuery &file) const;
};
inline Query operator~(const Query& query)
{ return new NotQuery(query); }
inline Query operator|(const Query& query_left,const Query& query_right)
{ return new OrQuery(query_left,query_right); }
inline Query operator&(const Query& query_left,const Query& query_right)
{ return new AndQuery(query_left,query_right); }
Query parse_expression(const std::string &QueryString);
}
// cpp file
#include "Query.h"
#include "TextQuery.h"
#include <set>
#include <algorithm>
#include <iostream>
using std::set;
using std::vector;
using std::string;
using std::ostream;
using std::inserter;
using std::set_difference;
using std::set_union;
using std::set_intersection;
namespace StringQuery{
set<TextQuery::line_no> NotQuery::eval(const TextQuery &file) const
{
set<line_no> has_val = query.eval(file);
set<line_no> not_val;
for(line_no lineSum = 0;lineSum < file.size();++lineSum)
{
if( has_val.find(lineSum)==has_val.end() )
not_val.insert(lineSum);
}
return not_val;
}
set<TextQuery::line_no> OrQuery::eval(const TextQuery &file) const
{
set<line_no> right = rhr.eval(file),
ret_lines = rhl.eval(file);
ret_lines.insert( right.begin(),right.end() );
return ret_lines;
}
set<TextQuery::line_no> AndQuery::eval(const TextQuery &file) const
{
set<line_no> rval = rhr.eval(file),
lval = rhl.eval(file);
set<line_no> retlines;
set_intersection( rval.begin(),rval.end(),lval.begin(),lval.end(),inserter(retlines,retlines.begin()) );
return retlines;
}
bool inputValidate(const std::string &QueryString)
{
std::string::size_type pos = QueryString.find("~|&");
if(std::string::npos != pos)
if( std::string::npos != QueryString.find("~|&",++pos) )
return false;
return true;
}
Query parse_expression(const std::string &QueryString)
{
vector<string> words;
vector<string> opers;
string::size_type pos_pre = 0;
string::size_type pos_cur = QueryString.find_first_of("~|&");
while(string::npos != pos_cur)
{
string word = QueryString.substr( pos_pre,pos_cur - pos_pre );
words.push_back(word);
string oper = QueryString.substr(pos_cur,1);
opers.push_back(oper);
pos_pre = pos_cur+1;
pos_cur = QueryString.find_first_of("~|&",pos_pre);
}
string word = QueryString.substr(pos_pre,QueryString.size()-pos_pre);
words.push_back(word);
vector<string>::const_reverse_iterator words_it = words.rbegin();
vector<string>::const_reverse_iterator opers_it = opers.rbegin();
Query query(*words_it);
words_it++;
for(;words_it != words.rend();words_it++)
{
if( opers_it != opers.rend() )
{
switch((*opers_it).at(0))
{
case '~':
query = ~query;
break;
case '|':
query = query|Query(*words_it);
words_it++;
break;
case '&':
query = query&Query(*words_it);
words_it++;
break;
default:
std::cerr << "It's an operator from Mars!";
}
opers_it++;
}
}
//Query query( *(new string("temp")) );
return query;
}
}
// Finder.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <conio.h>
#include "TextQuery.h"
#include "Query.h"
//#include <boost/regex.hpp>
//using namespace boost;
using std::string;
using std::set;
using std::cin;
using std::cout;
using std::endl;
void printResult(const string& word,const char* filename);
int _tmain(int argc, _TCHAR* argv[])
{
if(3 > argc)
{
cout << "Usage:program <Filename> <QueryWord> ." << endl;
}
else
{
string word;
for(int count = 2;count < argc;count++)
{
word += argv[count];
}
StringQuery::Query q( StringQuery::parse_expression(word) );
TextQuery tq;
tq.readFile(argv[1]);
q.display(std::cout);
set<TextQuery::line_no> rec = q.eval(tq);
set<TextQuery::line_no>::iterator it = rec.begin();
for(;it != rec.end();++it)
{
cout << " ( line " << *it << " ) " << tq.textLine(*it) << endl;
}
}
_getch();
return 0;
}
void printResult(const string& word,const char* filename)
{
TextQuery tq;
tq.readFile(filename);
set<TextQuery::line_no> res = tq.run_query(word);
cout << "Found " << res.size() << " items." << endl;
set<TextQuery::line_no>::iterator it = res.begin();
for(;it != res.end();++it)
{
cout << " ( line " << *it << " ) " << tq.textLine(*it) << endl;
}
}
#pragma once
#include "TextQuery.h"
#include <algorithm>
#include <iterator>
namespace StringQuery{
class QueryBase
{
friend class Query;
protected:
typedef TextQuery::line_no line_no;
virtual ~QueryBase(void){};
private:
virtual std::set<line_no> eval(const TextQuery& t) const = 0;
virtual std::ostream& display(std::ostream& os = std::cout) const = 0;
};
class Query
{
public:
friend Query operator~(const Query& );
friend Query operator|(const Query& ,const Query& );
friend Query operator&(const Query& ,const Query& );
std::set<TextQuery::line_no> eval(const TextQuery& tq) const
{
return q->eval(tq);
}
std::ostream& display(std::ostream& os) const
{
return q->display(os);
}
Query& operator=(const Query &);
public:
Query(const std::string &s);
Query(const Query& query):q(query.q),use(query.use){++*use;}
Query(QueryBase* qb):q(qb),use(new size_t(1)){}
~Query(void){decr_use();}
private:
QueryBase *q;
std::size_t *use;
inline void decr_use(void)
{
if(--*use==0)
{
delete q;
delete use;
}
}
};
inline std::ostream& operator<<(std::ostream& os,const Query &q)
{ return q.display(os); }
inline Query& Query::operator=(const Query &rhs)
{
++*rhs.use;
decr_use();
q = rhs.q;
use = rhs.use;
return *this;
}
class WordQuery:public QueryBase
{
friend class Query;
WordQuery(const std::string &s):query_word(s) { }
std::set<line_no> eval(const TextQuery &t) const
{ return t.run_query(query_word); }
std::ostream& display(std::ostream &os = std::cout) const
{ return os << query_word; }
std::string query_word;
};
inline
Query::Query(const std::string &s):q(new WordQuery(s)),
use(new std::size_t(1)) { }
class NotQuery:public QueryBase
{
friend Query operator~(const Query& query);
NotQuery(const Query& q):query(q) { }
std::set<line_no> eval(const TextQuery& file) const;
std::ostream& display(std::ostream& os = std::cout) const
{ return os << "~(" << query << ")"; }
const Query query;//implemente binding
};
class BinaryQuery:public QueryBase
{
protected:
BinaryQuery(const Query &rl,const Query &rr,const std::string &op):rhl(rl),rhr(rr),oper(op){}
std::ostream& display(std::ostream &os) const
{ return os << "~(" << rhl << "" << oper << " " << rhr << ")"; }
const Query rhl,rhr;
const std::string oper;
};
class OrQuery:public BinaryQuery
{
friend Query operator|(const Query &,const Query &);
OrQuery(const Query& rl,const Query& rr):BinaryQuery(rl,rr,"|"){}
std::set<line_no> eval(const TextQuery &file) const;
};
class AndQuery:public BinaryQuery
{
friend Query operator&(const Query &,const Query &);
AndQuery(const Query &rl,const Query &rr):BinaryQuery(rl,rr,"&"){}
std::set<line_no> eval(const TextQuery &file) const;
};
inline Query operator~(const Query& query)
{ return new NotQuery(query); }
inline Query operator|(const Query& query_left,const Query& query_right)
{ return new OrQuery(query_left,query_right); }
inline Query operator&(const Query& query_left,const Query& query_right)
{ return new AndQuery(query_left,query_right); }
Query parse_expression(const std::string &QueryString);
}
// cpp file
#include "Query.h"
#include "TextQuery.h"
#include <set>
#include <algorithm>
#include <iostream>
using std::set;
using std::vector;
using std::string;
using std::ostream;
using std::inserter;
using std::set_difference;
using std::set_union;
using std::set_intersection;
namespace StringQuery{
set<TextQuery::line_no> NotQuery::eval(const TextQuery &file) const
{
set<line_no> has_val = query.eval(file);
set<line_no> not_val;
for(line_no lineSum = 0;lineSum < file.size();++lineSum)
{
if( has_val.find(lineSum)==has_val.end() )
not_val.insert(lineSum);
}
return not_val;
}
set<TextQuery::line_no> OrQuery::eval(const TextQuery &file) const
{
set<line_no> right = rhr.eval(file),
ret_lines = rhl.eval(file);
ret_lines.insert( right.begin(),right.end() );
return ret_lines;
}
set<TextQuery::line_no> AndQuery::eval(const TextQuery &file) const
{
set<line_no> rval = rhr.eval(file),
lval = rhl.eval(file);
set<line_no> retlines;
set_intersection( rval.begin(),rval.end(),lval.begin(),lval.end(),inserter(retlines,retlines.begin()) );
return retlines;
}
bool inputValidate(const std::string &QueryString)
{
std::string::size_type pos = QueryString.find("~|&");
if(std::string::npos != pos)
if( std::string::npos != QueryString.find("~|&",++pos) )
return false;
return true;
}
Query parse_expression(const std::string &QueryString)
{
vector<string> words;
vector<string> opers;
string::size_type pos_pre = 0;
string::size_type pos_cur = QueryString.find_first_of("~|&");
while(string::npos != pos_cur)
{
string word = QueryString.substr( pos_pre,pos_cur - pos_pre );
words.push_back(word);
string oper = QueryString.substr(pos_cur,1);
opers.push_back(oper);
pos_pre = pos_cur+1;
pos_cur = QueryString.find_first_of("~|&",pos_pre);
}
string word = QueryString.substr(pos_pre,QueryString.size()-pos_pre);
words.push_back(word);
vector<string>::const_reverse_iterator words_it = words.rbegin();
vector<string>::const_reverse_iterator opers_it = opers.rbegin();
Query query(*words_it);
words_it++;
for(;words_it != words.rend();words_it++)
{
if( opers_it != opers.rend() )
{
switch((*opers_it).at(0))
{
case '~':
query = ~query;
break;
case '|':
query = query|Query(*words_it);
words_it++;
break;
case '&':
query = query&Query(*words_it);
words_it++;
break;
default:
std::cerr << "It's an operator from Mars!";
}
opers_it++;
}
}
//Query query( *(new string("temp")) );
return query;
}
}
// Finder.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <conio.h>
#include "TextQuery.h"
#include "Query.h"
//#include <boost/regex.hpp>
//using namespace boost;
using std::string;
using std::set;
using std::cin;
using std::cout;
using std::endl;
void printResult(const string& word,const char* filename);
int _tmain(int argc, _TCHAR* argv[])
{
if(3 > argc)
{
cout << "Usage:program <Filename> <QueryWord> ." << endl;
}
else
{
string word;
for(int count = 2;count < argc;count++)
{
word += argv[count];
}
StringQuery::Query q( StringQuery::parse_expression(word) );
TextQuery tq;
tq.readFile(argv[1]);
q.display(std::cout);
set<TextQuery::line_no> rec = q.eval(tq);
set<TextQuery::line_no>::iterator it = rec.begin();
for(;it != rec.end();++it)
{
cout << " ( line " << *it << " ) " << tq.textLine(*it) << endl;
}
}
_getch();
return 0;
}
void printResult(const string& word,const char* filename)
{
TextQuery tq;
tq.readFile(filename);
set<TextQuery::line_no> res = tq.run_query(word);
cout << "Found " << res.size() << " items." << endl;
set<TextQuery::line_no>::iterator it = res.begin();
for(;it != res.end();++it)
{
cout << " ( line " << *it << " ) " << tq.textLine(*it) << endl;
}
}
相关文章推荐
- C++文本查询程序 C++Primer练习12.28 使用vector,map,set容器保存来自文件的数据并生成查询结果
- C++文本查询程序 定义类管理数据 用智能指针 C++Primer练习12.30
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 不要定义类和智能指针管理数据 C++Primer练习12.28 使用vector,map,set容器保存来自文件的数据并生成查询结果
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 定义类管理数据 用智能指针 C++Primer练习12.30
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 C++Primer练习12.28 使用vector,map,set容器保存来自文件的数据并生成查询结果
- C++文本查询程序 定义类管理数据 用智能指针 C++Primer练习12.30
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 不要定义类和智能指针管理数据 C++Primer练习12.28 使用vector,map,set容器保存来自文件的数据并生成查询结果
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 定义类管理数据 用智能指针 C++Primer练习12.30
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 C++Primer练习12.28 使用vector,map,set容器保存来自文件的数据并生成查询结果
- C++文本查询程序 定义类管理数据 用智能指针 C++Primer练习12.30
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 不要定义类和智能指针管理数据 C++Primer练习12.28 使用vector,map,set容器保存来自文件的数据并生成查询结果
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 定义类管理数据 用智能指针 C++Primer练习12.30