本节中使用类的继承方式重写了文本查询程序,支持多种查询策略:或,与,非。

其中Query是提供给用户使用的类,含有两个接口:evalrepeval用于查找对应的单词出现的文本,rep用于输出用户指定的查询内容。
Query_base是抽象基类,WordQuery是普通查询策略,NotQuery是取非查询策略。对于双目查询策略,定义了一个新的抽象基类BinaryQueryAndQueryOrQuery是继承于它的两个与/非查询策略。

对于用户的查询来说,一个典型表达式:

用户代码:
main.cpp

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include "Query.h"
#include "TextQuery.h"
#include "QueryResult.h"using namespace std;int main(int argc, char **argv) {ifstream f("test.txt");if (f) {TextQuery t(f);Query q = Query("whilst") & Query("the");cout << q.rep() << endl;QueryResult answer = q.eval(t);print(cout, answer);}else {cout << "Cannot open file" << endl;exit(1);}return 0;
}

源文本:

Oscar Fingal O'Flahertie Wills Wilde (16 October 1854 to 30 November 1900) was an Irish writer, poet, and prominent aesthete who, after writing in different forms throughout the 1880s, became one of London's most popular playwrights in the early 1890s. Today he is remembered for his epigrams, plays and the tragedy of his imprisonment, followed by his early death.
Wilde's parents were successful Dublin intellectuals and from an early age he was tutored at home, where he showed his intelligence, becoming fluent in French and German. He attended boarding school for six years, then matriculated to university at seventeen years of age. Reading Greats, Wilde proved himself to be an outstanding classicist, first at Dublin, then at Oxford. His intellectual horizons were broad: he was deeply interested in the rising philosophy of aestheticism (led by two of his tutors, Walter Pater and John Ruskin) though he also profoundly explored Roman Catholicism and finally converted on his deathbed.
After university Wilde moved to London, into fashionable cultural and social circles. As a spokesman for aestheticism, he tried his hand at various literary activities; he published a book of poems, lectured America and Canada on the new "English Renaissance in Art" and then returned to London to work prolifically as a journalist for four years. Known for his biting wit, flamboyant dress, and glittering conversation, Wilde was one of the best known personalities of his day. At the turn of the 1890s, he refined his ideas about the supremacy of art in a series of dialogues and essays; though it was his only novel, The Picture of Dorian Gray, which began a more lasting oeuvre. The opportunity to construct aesthetic details precisely, combined with larger social themes, drew Wilde to writing drama. He wrote Salome in French in Paris in 1891, but it was refused a licence. Unperturbed, Wilde produced four society comedies in the early 1890s, which made him one of the most successful playwrights of late Victorian London.
At the height of his fame and success, whilst his masterpiece, The Importance of Being Earnest, was still on stage in London, Wilde sued his lover's father for libel. After a series of trials, Wilde was convicted of gross indecency with other men and imprisoned for two years, held to hard labour. In prison he wrote De Profundis, a long letter which discusses his spiritual journey through his trials, forming a dark counterpoint to his earlier philosophy of pleasure. Upon his release he left immediately for France, never to return to Ireland or Britain. There he wrote his last work, The Ballad of Reading Gaol, a long poem commemorating the harsh rhythms of prison life. He died destitute in Paris at the age of forty-six

Query.h

#pragma once
#include <iostream>
#include <memory>
#include "Query_base.h"
#include "TextQuery.h"
#include "QueryResult.h"class Query {friend Query operator~(const Query &q);friend Query operator&(const Query &lhs, const Query &rhs);friend Query operator|(const Query &lhs, const Query &rhs);friend ostream &operator<<(ostream &os, const Query &q);
public:Query(const std::string &);QueryResult eval(const TextQuery &t) const;std::string rep() const;
private:Query(std::shared_ptr<Query_base> query);std::shared_ptr<Query_base> q;
};

Query.cpp

#include "stdafx.h"
#include "Query.h"
#include "WordQuery.h"
#include "BinaryQuery.h"
#include "AndQuery.h"
#include "OrQuery.h"
#include "NotQuery.h"
#include "QueryResult.h"Query operator~(const Query &q) {return std::shared_ptr<Query_base>(new NotQuery(q));
}Query operator&(const Query &lhs, const Query &rhs) {return std::shared_ptr<Query_base>(new AndQuery(lhs,rhs));
}Query operator|(const Query &lhs, const Query &rhs) {return std::shared_ptr<Query_base>(new OrQuery(lhs, rhs));
}std::ostream &operator<<(std::ostream &os, const Query &q) {//print(os, q->eval(const TextQuery &t));os << q.rep() << endl;return os;
}Query::Query(const std::string &s): q(std::shared_ptr<Query_base>(new WordQuery(s))) {}QueryResult Query::eval(const TextQuery &t) const {return q->eval(t);
}std::string Query::rep() const {return q->rep();
}Query::Query(std::shared_ptr<Query_base> query): q(query) {}

Query_base.h

#pragma once
#include "TextQuery.h"
#include "QueryResult.h"class Query_base {friend class Query;
protected:using line_no = TextQuery::line_no;virtual ~Query_base() {};
private:virtual QueryResult eval(const TextQuery &t) const = 0;virtual std::string rep() const = 0;
};

BinaryQuery.h

#pragma once
#include "Query.h"
#include "Query_base.h"class BinaryQuery : public Query_base {protected:BinaryQuery(const Query &lhs, const Query &rhs, const std::string &s);virtual std::string rep() const override;Query lhs, rhs;std::string ops;
};

BinaryQuery.cpp

#include "stdafx.h"
#include "BinaryQuery.h"BinaryQuery::BinaryQuery(const Query &lhs, const Query &rhs, const std::string &s): lhs(lhs), rhs(rhs), ops(s) {}std::string BinaryQuery::rep() const {return ops;
}

WordQuery.h

#pragma once
#include "Query.h"
#include "Query_base.h"class WordQuery : public Query_base {friend class Query;
private:WordQuery(const std::string &s);virtual QueryResult eval(const TextQuery &t) const override;virtual std::string rep() const override;std::string query_word;
};

WordQuery.cpp

#include "stdafx.h"
#include "WordQuery.h"WordQuery::WordQuery(const std::string &s): query_word(s) {}QueryResult WordQuery::eval(const TextQuery &t) const {return t.query(query_word);
}std::string WordQuery::rep() const {return query_word;
}

NotQuery.h

#pragma once
#include "Query.h"
#include "Query_base.h"class NotQuery : public Query_base {friend Query operator~(const Query &q);
private:NotQuery(const Query &q);virtual QueryResult eval(const TextQuery &t) const override;virtual std::string rep() const override;Query query;
};

NotQuery.cpp

#include "stdafx.h"
#include "NotQuery.h"NotQuery::NotQuery(const Query &q): query(q) {}QueryResult NotQuery::eval(const TextQuery &t) const {auto result = t.query(query.rep());auto beg = result.get_begin();auto end = result.get_end();auto file = result.get_file();size_t size= file->size();auto ret_lines = std::make_shared<set<TextQuery::line_no>>();if (beg == end) {for (size_t i = 0; i < size; ++i) {ret_lines->insert(i);}} else {while (beg != end) {for (size_t i = 0; i < size; ++i) {if (*beg != i) {ret_lines->insert(i);}}++beg;}}return QueryResult(rep(), file, ret_lines);
}std::string NotQuery::rep() const {return query.rep();
}

AndQuery.h

#pragma once
#include "Query.h"
#include "BinaryQuery.h"class AndQuery : public BinaryQuery {friend Query operator&(const Query &, const Query &);AndQuery(const Query &lhs, const Query &rhs);virtual QueryResult eval(const TextQuery &t) const override;
};

AndQuery.cpp

#include "stdafx.h"
#include "AndQuery.h"
#include <algorithm>
#include <iterator>AndQuery::AndQuery(const Query &lhs, const Query &rhs): BinaryQuery(lhs, rhs, "&") {}QueryResult AndQuery::eval(const TextQuery &t) const {auto left = lhs.eval(t);auto right = rhs.eval(t);auto ret_lines = std::make_shared<set<TextQuery::line_no>>();std::set_intersection(left.get_begin(), left.get_end(),right.get_begin(), right.get_end(),inserter(*ret_lines, ret_lines->begin()));return QueryResult(lhs.rep() + "&" + rhs.rep(), left.get_file(), ret_lines);
}

OrQuery.h

#pragma once
#include "Query.h"
#include "BinaryQuery.h"class OrQuery : public BinaryQuery {friend Query operator|(const Query &, const Query &);OrQuery(const Query &lhs, const Query &rhs);virtual QueryResult eval(const TextQuery &t) const override;
};

OrQuery.cpp

#include "stdafx.h"
#include "OrQuery.h"OrQuery::OrQuery(const Query &lhs, const Query &rhs): BinaryQuery(lhs, rhs, "|") {}QueryResult OrQuery::eval(const TextQuery &t) const {auto left = lhs.eval(t);auto right = rhs.eval(t);auto ret_lines = std::make_shared<set<TextQuery::line_no>>(left.get_begin(),left.get_end());ret_lines->insert(right.get_begin(), right.get_end());return QueryResult(lhs.rep() + "|" + rhs.rep(), left.get_file(), ret_lines);
}

TextQuery.h

#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include "QueryResult.h"using namespace std;class QueryResult;class TextQuery {public:using line_no = vector<string>::size_type;TextQuery(ifstream &f);QueryResult query(const string &s) const;
private:map<string, shared_ptr<set<line_no>>> m_vm;shared_ptr<vector<string>> m_text;
};

TextQuery.cpp

#include "stdafx.h"
#include <sstream>
#include "TextQuery.h"TextQuery::TextQuery(ifstream &f): m_text(new vector<string>) {string tmp;line_no pos = 1;while (getline(f, tmp)) {m_text->push_back(tmp);stringstream line(tmp);string word;while (line >> word) {auto &lines = m_vm[word];if (!lines) {lines.reset(new set<line_no>);}lines->insert(pos);}++pos;}
}QueryResult TextQuery::query(const string &s) const {shared_ptr<set<line_no>> nodata(new set<line_no>());auto itr = m_vm.find(s);if (itr == m_vm.end()) {return QueryResult(s, m_text, nodata);} else {return QueryResult(s, m_text, itr->second);}
}

QueryResult.h

#pragma once
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <memory>
#include "TextQuery.h"using namespace std;class QueryResult {friend void print(std::ostream &os, const QueryResult &q);
public:using line_no = vector<string>::size_type;QueryResult(const string target, shared_ptr<vector<string>> sv, shared_ptr<set<line_no>> sl);set<line_no>::const_iterator get_begin() const;set<line_no>::const_iterator get_end() const;shared_ptr<vector<string>> get_file() const;
private:string m_target;shared_ptr<vector<string>> m_text;shared_ptr<set<line_no>> m_lines;
};

QueryResult.cpp

#include "stdafx.h"
#include "QueryResult.h"void print(std::ostream &os, const QueryResult &q) {os << "The word: " << q.m_target << endl;os << "Occur at line: " << endl;size_t index = 0;for (const auto i:*q.m_lines) {os << i << " with string: " << (*q.m_text)[index] << endl;++index;}
}QueryResult::QueryResult(const string target, shared_ptr<vector<string>> text, shared_ptr<set<TextQuery::line_no>> lines): m_target(target), m_text(text), m_lines(lines) {}set<TextQuery::line_no>::const_iterator QueryResult::get_begin() const {return m_lines->cbegin();
}set<TextQuery::line_no>::const_iterator QueryResult::get_end() const {return m_lines->cend();
}shared_ptr<vector<string>> QueryResult::get_file() const {return m_text;
}

Result:

15.9 文本查询程序再探(继承)相关推荐

  1. C++ 容器的综合应用的一个简单实例——文本查询程序

    [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例. 通过实现一个简单的文本查询程序,希望能够对C++的容器学习有更深的理解. 由 ...

  2. c++ primer--容器的综合应用:文本查询程序

    c++ primer–容器的综合应用:文本查询程序 我们的程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词.查询的结果是该单词出现的次数,并列出每次出现所在的行.如果某单词在同一行中多 ...

  3. 【Smart_Point】动态内存与智能指针实战:文本查询程序(设计set,map,智能指针的应用)

    文章目录 Cpp读入结构性数组 文本查询程序 文本查询程序本版1 Cpp读入结构性数组 #include<sstream> #include<iostream> #includ ...

  4. C++自学笔记_文本查询程序_《C++ Primer》

    <C++ Primer> 第10章结束,用一个文本查询程序结束本章 :) 程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词.查询的结果是该单词出现的次数,并列出每次出现所在 ...

  5. C++ primer 第12章 12.3 使用标准库:文本查询程序

    文章目录 使用标准库:文本查询程序 文本查询程序设计 数据结构 在类之间共享数据 自己的文本查询程序 书中的文本查询程序 使用标准库:文本查询程序 我们将实现一个简单的文本查询程序,作为标准库相关内容 ...

  6. 容器的综合应用:文本查询程序

    需求 程序读取用户指定的任意文本文件,允许用户从该文件中查找单词.查询结果是该单词出现的次数,并列出每次出现所在行,如果某单词在同一行中多次出现,程序将只显示该行一次.行号按升序显示,即第 7 行应该 ...

  7. c++ primer文本查询程序 自编加强版(c++primer5th 练习12.32-33)

    //文件 functions.cc#include <iostream> #include <string> #include <vector> #include ...

  8. 12.3 文本查询程序

    未封装版本 #include <iostream> #include <fstream> #include <string> #include <vector ...

  9. c++primer 12.3.1文本查询程序

    提示:不完全类型只能在优先的情况下使用,可以定义以这个类型作为函数的参数类型或者函数返回值类型,也可以定义这个类型的指针或者引用. //文件functions.cc #include <stri ...

最新文章

  1. 【面向对象】第一单元总结——表达式求导
  2. O2O防刷单并没那么难,看完这个你也会反作弊了
  3. 什么是oracle的临时表??
  4. spring框架介绍_Spring框架介绍
  5. Git push 时每次都需要密码的疑惑
  6. java多项式和_在Java中查找多项式的根
  7. angular之DI理解
  8. 蓝桥杯 ALGO-106 算法训练 6-3判定字符位置
  9. 条件编译宏定义_C语言学习- 预处理指令2 - 条件编译
  10. python环境精简版_【Python专题(一)】Python环境搭建
  11. UBUNTU安装之后要配置的内容
  12. Java三大特性的第一个分水岭——封装性
  13. tomcat热部署(springboot项目)
  14. Cubic interpolation
  15. python常见开源库整理
  16. SQL Server 阻止保存要求重新创建表的更改
  17. 计算机网络----宽带速度kbps、KB、Mbps
  18. 第一周------继续
  19. 阿里2017校园招聘电话面试总结
  20. java对象克隆效率_fastclone

热门文章

  1. 因为一个bug来深入探讨下分页插件PageHelper
  2. 靠肝的爬塔不优雅——养成手游《古今江湖》
  3. IOC BeanFactory XML之旅
  4. 怎么通过Unity和谷歌纸盒做一个VR游戏?(译)
  5. 【已解决】Nginx基于多端口、多域名配置
  6. html登录图片验证码的实现
  7. 电力爱陆通公专一体模块,国网加密模块,国网硬件加密模块的工作原理
  8. 【游戏开发】2D RPG游戏
  9. 写给安徽合肥高三的你——少年不惧岁月长,敢挽桑弓射玉衡
  10. 知网 - 情感分析用词语集(beta版)- 情感词库