【C++ Primer Chapter12&15】TextQueries Project

TextQueries Project
 
问题:
我们将实现一个简单的文本查询程序。
我们的程序将允许用户在给定的文件中搜索可能出现的单词。
查询的结果将是单词出现的次数和该单词出现的行列表。
如果一个单词在同一行中出现多次,我们将只显示该行一次。行将按升序显示。
 
例子:
在给定输入文件中查找element。输出:
element occurs 112 times
(line 36) A set element contains only a key;
(line 158) operator creates a new element
(line 160) Regardless of whether the element
(line 168) When we fetch an element from a map, we
(line 214) If the element is not found, find returns
......

 

实现:
  • 功能:1)按行读入,记录单词出现的行号。2)输出的时候,能够获取行号对应的行,以升序保存结果。
  • 具体:1)vector<string>按行保存输入文件,使用下标可以按行号找到对应行的句子。2)istringstream处理字符串,将输入文件分行。3)set<int>保存单词出现的行号结果。4)map<string,set<int>>保存每个文件中每个单词对应的结果。
  • 数据结构:1)TextQuery类:处理输入文件并查询。2)QueryResult类:结果,输出结果。
  • 细节:QueryResult类用于表示查询的结果。这些数据存储在TextQuery类型的对象中。如何访问?1)拷贝;2)智能指针。
  • 使用智能指针可以避免QueryResult指向的TextQuery的data在TextQuery被销毁后无法访问的情况。(只要智能指针的reference count大于0,指针指向的对象即使在指针被销毁后也不会被释放。)
 
TextQueries Project Pro
 
功能:
  • 单词查询。查找与给定字符串匹配的所有行:
Executing Query for: Daddy 
Daddy occurs 3 times
(line 2) Her Daddy says when the wind blows
(line 7) "Daddy, shush, there is no such thing,"
(line 10) Shyly, she asks, "I mean, Daddy, is there?"
  • 非查询。使用~操作符,产生与查询不匹配的行:
Executing Query for: ~(Alice)
~(Alice) occurs 9 times
(line 2) Her Daddy says when the wind blows
(line 3) through her hair, it looks almost alive,
(line 4) like a fiery bird in flight.
  • 或查询。使用 | 操作符返回匹配两个查询中的任意一个的行:
Executing Query for: (hair | Alice)
(hair | Alice) occurs 2 times
(line 1) Alice Emma has long flowing red hair.
(line 3) through her hair, it looks almost alive,
  • 与查询。使用 & 操作符的查询返回匹配两个查询的行:
Executing query for: (hair & Alice)
(hair & Alice) occurs 1 time
(line 1) Alice Emma has long flowing red hair.
  • 任意操作符的结合。
Executing Query for: ((fiery & bird) | wind)
((fiery & bird) | wind) occurs 3 times
(line 2) Her Daddy says when the wind blows
(line 4) like a fiery bird in flight.
(line 5) A beautiful fiery bird, he tells her,
 
具体:
  • eval(),它接受一个TextQuery对象并返回一个QueryResult。eval函数将使用给定的TextQuery对象来查找查询的匹配行。
  • rep(),它返回底层查询的字符串表示形式。该函数将被eval()使用来创建一个表示匹配的QueryResult,输出操作符将使用该函数打印查询表达式。
 
实现:
  1. Query_base:抽象基类。包含eval()和rep()两个纯虚函数。
  2. WordQuery和NotQuery:直接从Query_base得到的派生类。
  3. BinaryQuery:抽象基类。 表示用两个操作数的查询。
  4. AndQuery和OrQuery:继承BinaryQuery。
 
 
细节:
用户代码不会直接使用继承的类。需要一个和用户交互的接口类Query(会隐藏类继承结构)。
  • Query类存储一个指向Query_base的指针。该指针将被绑定到派生自Query_base的类对象上。
  • Query提供Query_base相同的操作:eval() 计算关联的查询,和rep()生成查询的字符串版本。 它还将定义一个重载输出操作符来显示关联的查询。
  • 用户只能通过对Query对象的操作间接地创建和操作Query_base对象。
  • 在Query对象上定义三个重载操作符,以及一个接受字符串的Query构造函数。这些函数都将动态分配一个派生自Query_base的类型的新对象。
         1)& 操作符将生成一个绑定到一个新的AndQuery的Query。
         2)|  操作符将生成一个绑定到一个新的OrQuery的Query。
         3)~ 操作符将生成一个绑定到新的NotQuery的Query。
         4)Query构造函数接受一个字符串将生成一个新的WordQuery。
将查询表示为C++表达式
((fiery & bird) | wind) :  
Query q = Query("fiery") & Query("bird") | Query("wind");
 
操作:
  • 类的使用者
  • 类的实现者
Query Program Interface Classes and Operations
 
TextQuery:    Class that reads a given file and builds a lookup map. This class has a query operation that takes a string argument and returns a QueryResult
              representing the lines.
QueryResult:  Class that holds the results of a query operation.
Query:        Interface class that points to an object of a type derived from Query_base.
Query q(s):   Binds the Query q to a new wordQuery holding the string s.
q1 & q2:      Returns a Query bound to a new AndQuery object holding q1 and q2.
q1 | q2:      Returns a Query bound to a new OrQuery object holding a1 and q2.
~q:           Returns a Query bound to a new NotQuery object holding a.
 
Query Program Implementation Classes
 
Query_base:    Abstract base class for the query classes:
wordQuery:     Class derived from Query_base that looks for a given word.
NotQuery:      Class derived from Query_base that represents the set of lines in which its Query operand does not appear.
BinaryQuery:   Abstract base class derived from Query_base that represents queries with two Query operands.
orQuery:       Class derived from Binaryouery that returns the union of the linenumbers in which its two operands appear.
AndQuery:      Class derived from BinaryQuery that returns the intersection of the linenumbers in which its two operands appear.

  

 
 
 
 
posted @ 2021-05-29 13:04  萌新的学习之路  阅读(44)  评论(0编辑  收藏  举报