• 程序的编写/数据结构和操作/容器的应用/查询程序


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

    该程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词。

    查询的结果是该单词出现的次数,并列出每次出现的行。如果某单词在同一行多次出现,程序将只显示该行一次。行号按升序显示。

     

    设计程序的一个良好习惯是首先将程序所涉及的操作列出来。

    明确需要提供的操作有助于建立需要的数据结构和实现这些行为。

    从需求出发,我们的程序需要支持如下任务:

    1),它必须允许用户指明要处理的文件名字。程序将储存该文件的内容,以便输出每个但系所在的原始行。

    2),它必须将每一行分解为各个单词,并记录每个单词所在的所有行。在输出行号时,应保证以升序输出,并且不重复。

    3),对特定单词的查询将返回出现该单词的所有行的行号

    4),输出某单词所在的行文本时,程序必须能根据给定的行号从输入文件中获取相应的行。

    //所谓类,无非数据,和 函数

    //程序也是如此。

    1数据结构

    用一个简单的类实现这个程序,配合使用几种容器,可以满足上述要求

    1),使用一个vector<string>类型的对象储存整个输入文件的副本。

    输入文件的每一行是该vector对象的一个元素。因而,在希望输出某一行时,只需以行号为下标获取该行所在的元素即可。

    2),将每个单词所在的行号存储在一个set容器对象中。使用set就可以确保每行只有一个条目,而且行号将自动按升序排列。

    3),使用一个map容器将每个单词与一个set容器对象关联起来,该set容器对象记录此单词所在的行号。

     终上所述,需要定义的类将有两个数据成员:储存输入文件的vector 对象,以及一个map容器对象,该对象关联每个输入的单词以及记录该单词所在行号的set容器对象。 

    2操作

    对于类还要求有良好的接口

    一个重要的设计策略首先要确定:查询函数需返回存储一组行号的set对象。这个返回类型应该如何设计?

    查询的过程相当简单:使用下标访问map对象获取关联的set对象即可。唯一的问题是如何返回所找到的set对象。

    安全的设计方案是返回该set对象的副本。但这就意味着要复制set中的每一个元素。

    如果处理的是一个相当庞大的文件,则复制set对象的代价会非常昂贵。

    其他可行的方法包括:返回一个pair对象,存储一对指向set中元素的迭代器;或者返回set对象的const引用。

     

    第一,三,四任务是使用这个类的程序员将执行的动作。第二个任务则是类的内部任务。

    将这四个任务映射为类的成员函数,则类的接口需提供下列三个public函数。

    ——Read_file成员函数,其形参为一个ifstream&类型对象。 该函数每次从文件中读入一行,并将它保存在vector容器中。输入完毕后,read_file将创建关联每个单词及其所在行的map容器。

    ——Run_query 成员函数,其形参为一个string类型对象,返回一个set对象,该set对象包含出现该string对象的所有行的行号。

    ——Text_line成员函数,其形参为一个行号,返回输入文本中该行对应的文本行。

    无论run_query还是text_line都不会修改调用此函数的对象,所以,将这两个操作定义为const成员函数。

     

    为实现read_file功能,还需定义两个private函数来读取输入文本和创建map容器:

    ——store_file函数读入文件,并将文件内容存储在vector 容器中。

    ——build_map函数将每一行分解为各个单词,创建map容器对象,同时记录每个单词出现的行号

     

      #include <vector>
      #include <map>
      #include <fstream>
      #include <set>
     
    class TextQuery
    {
    public:
        //typedef to make declarations easier
        typedef std::vector<std::string>::size_type line_no;
        /*interface:
            read_file builds internal date structures for the given file
            run_query finds the given word and returns set of lines on which it appears
            text_line returns a requeted line from the input line    
        */ 
        void read_file(std::ifstream &is)
        { 
            store_file(is); build_map(); 
        }
        std::set< line_no > run_query(const std::string&) const;
        std::string text_line(line_no) const;
    private:
        //utility functions used by read_line
        void store_file(std::ifstream&);    //store input file
        void build_map();                    //associated each word with a set of line numbers
        //remember the whole input file
        std::vector<std::string> lines_of_text;
        //map word to set of the lines on which it occures
        std::map< std::string, std::set< line_no >  > word_map;
     } ;

     10.6 p325  C++primer

  • 相关阅读:
    Github开源人脸识别项目face_recognition
    yolo源码解析(3):进行简单跳帧
    [转]详细解读TrueSkill 排名系统
    yolo源码解析(3):视频检测流程
    Java中replace和replaceall的区别
    对input输入框日期显示格式化
    Eclipse修改编码字体
    Eclipse修改控制台字体
    Eclipse文档注释导出doc
    数组的定义方式及初始化
  • 原文地址:https://www.cnblogs.com/aprilapril/p/2971502.html
Copyright © 2020-2023  润新知