【足迹C++primer】41、文本查询程序

/**
* 功能:使用标准库:文本查询程序
* 时间:2014年7月10日09:10:15
* 作者:cutter_point
*/

#include<iostream>
#include<map>
#include<set>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<memory>

using namespace std;

using line_no=vector<string>::size_type;

/**************************************
定义TextQuery类
**************************************/
class QueryResult;  //为了定义函数query的返回类型,前向申明
class TextQuery
{
public:
    TextQuery(ifstream&);
    QueryResult query(const string&) const;
private:
    shared_ptr<vector<string>> file;        //输入文件
    //每个单词到它所在的行数的集合映射
    map<string, shared_ptr<set<line_no>>> wm;
};

/*
读取输入文件并建立单词到行号的映射
*/
TextQuery::TextQuery(ifstream &is):file(new vector<string>)
{
    string text;
    while(getline(is, text))    //对应文件中每行
    {
        file->push_back(text);  //保存这行文本
        int n=file->size();     //行号,从第1行开始
        istringstream line(text);   //将文本分解为单词,istringstream是以空格为结束
        string word;
        while(line>>word)   //对应每行的每个单词
        {
            //如果单词不再wm中,就以它为下标在wm中添加一项
            auto &lines=wm[word];   //lines是一个shared_ptr,有了key值,但是没有value
            if(!lines)      //当我们第一次遇到这个单词的时候,此指针为空
            {
                lines.reset(new set<line_no>);  //吧a指向的内置指针b,否则置空,a.reset(b)
            }

            lines->insert(n);   //将此行插入set中
        }
    }
}
/**************************************
QueryResult类
**************************************/
class QueryResult
{
    friend ostream& print(ostream&, const QueryResult&);
public:
    QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>> f):sought(s),lines(p),file(f){}
private:
    string sought;      //查询单词
    shared_ptr<set<line_no>> lines;     //出现的行号
    shared_ptr<vector<string>> file;       //输入文件
};
//make_plural判断是否有元素的函数
inline string make_plural(size_t ctr, const string &word, const string &ending)
{
    return (ctr>1) ? word+ending : ending;
}

/*
友元函数实现
*/
ostream& print(ostream & os, const QueryResult & qr)
{
    //如果找到了单词,打印出现的次数,和出现的位置
    //如果找到了单词,打印出现的次数
    os<<qr.sought<<" occurs "<<qr.lines->size()<<" "<<make_plural(qr.lines->size(), "time", "s")<<endl;
    //打印单词出现的每一行
    for(auto num : *qr.lines)   //对set中每个单词
    {
        //避免重0行开始给用户带来困惑
        os<<"\t(line "<<num<<")"<<*(qr.file->begin()+num-1)<<endl;
    }
    return os;
}

/*
用QueryResult中的数据定义TextQuery中的函数
*/
QueryResult
TextQuery::query(const string &sought) const
{
    //如果未找到sought,我们将返回一个指向此set的指针
    static shared_ptr<set<line_no>> nodata(new set<line_no>);
    //使用find而不是下标运算来查找单词,避免将单词添加进去了
    auto loc=wm.find(sought);
    if(loc == wm.end())
        return QueryResult(sought, nodata, file);   //未找到
    else
        return QueryResult(sought, loc->second, file);
}

/**************************************
使用TextQuery类
**************************************/
void runQueries(ifstream &infile)
{
    //infile是一个ifstream,指向我们要处理的文件
    TextQuery tq(infile);   //保存文件并建立查询map
    //与用户交互:提示用户输入要查询的单词,完成查询并打印结果
    while(true)
    {
        cout<<"enter word to look for , or q to quit: ";
        string s;
        //若遇到文件结尾或输入'q'时结束循环
        if(!(cin>>s) || s == "q")
            break;        //指向查询并打印结果
        print(cout, tq.query(s))<<endl;
    }
}

int main()
{
    ifstream infile("test.txt");

    runQueries(infile);

    return 0;
}

【足迹C++primer】41、文本查询程序,布布扣,bubuko.com

时间: 2024-10-14 04:26:25

【足迹C++primer】41、文本查询程序的相关文章

【足迹C++primer】56、文本查询程序

/** * 功能:文本查询程序 * 时间:2014年7月23日10:26:09 * 作者:cutter_point */ #include<iostream> #include<algorithm> #include<memory> #include<set> #include<map> #include<fstream> #include<sstream> using namespace std; /* Alice Em

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

<C++ Primer> 第10章结束,用一个文本查询程序结束本章 :) 程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词.查询的结果是该单词出现的次数,并列出每次出现所在的行.如果某单词在同一行 中多次出现,程序将只显示该行一次.行号按照升序显示. 程序支持以下任务: · 它必须允许用户指明要处理的文件的名字.程序将存储该文件的内容,以便输出每个单词所在的原始行. · 它必须将每一行分解为各个单词,并记录每个单词所在的行.在输出行号时,应保证以升序输出,并且不重复. · 对特

C++ Primer 学习笔记_38_STL实践与分析(12)--容器的综合应用:文本查询程序

STL 实践与分析 -- 容器的综合应用:文本查询程序 引言: 本章中最重点的实例,因为不需要用到 multiset 与 multimap 的内容,于是将这一小节提到了前面,通过这个实例程序,大师分析问题的智慧,大师的编程风格,大师对程序的控制能力,由此可见一斑.因此,我对这一小节的内容几乎不做修改,或只做很小的更改(因为有些东西不同人有不同的理解),搬出来,以供大家仔细品读. 要求: 我们的程序将读取用户指定的 任意文本文件 , 然后允许用户从该文件中查找单词. 查询的结果是该单词出现的次数 

第十四篇:一个文本查询程序的实现

前言 本文将讲解一个经典的文本查询程序,对前面所学的容器相关知识进行一个从理论到实际的升华,同时也对即将学习的面向对象知识来一次初体验. 程序描述 要求实现这样一个程序:读取用户指定的文件,然后允许用户从中查找某个单词所在的位置. 一个面向过程的落后的设计思想 将待检索文件以行为单位存放到Vector容器中,然后遍历容器,将容器内元素依次转存到字符串流对象中,然后在内层遍历这个字符串流对象,检索是否存在与给定单词匹配的单词.如果有则输出该行内容以及该行序号. 落后的原因及先进的设计思想 这是我以

文本查询程序

我们实现一个简单的文本查询程序.我们的程序允许用户在一个给定文件中查询单词,查询结果是单词在文件中出现的次数及所在行的列表.如果一个单词在一行中出现多次,此行只列出一次. #include<iostream> #include<map> #include<set> #include<string> #include<vector> #include<fstream> #include<sstream> #include&l

使用标准库:文本查询程序

使用标准库:文本查询程序 class QueryResult { friend std::ostream& print(std::ostream&,cost QueryResult&); public: Queryresult(std::string s, std::shared_ptr<std::set<line_no>> p, std::shared_ptr<std::vector<std::string>>f): sought(

C++ Primer中文本查询示例Query的实现

最近在看C++ Primer复习C++的语法,看到书中15.9章中的文本查询示例时,觉得设计得非常不错,于是便动手照着实现了一个,修改了很久终于运行成功了,从中也学习到了很多的语法.下面把实现与总结分享给大家: 首先是在10.6.2节中实现的TextQuery类: TextQuery.h #ifndef __TestC____TextQuery__ #define __TestC____TextQuery__ #include <iostream> #include <vector>

C++ Primer第四版 15.9 再谈文本查询 程序实现

编程过程中发现书本中的示例程序并不完全,某些地方存在错误,现已改正并添加少许注释.. 1 #include<iostream> 2 #include<fstream> 3 #include<sstream> 4 #include<vector> 5 #include<map> 6 #include<set> 7 #include<algorithm> 8 #include<stdexcept> 9 using

&lt;&lt;c++ primer&gt;&gt;文本查询程序

#ifndef _TEXTQUERY_H #define _TEXTQUERY_H #include <vector> #include <string> #include <set> #include <map> #include <fstream> #include <sstream> class TextQuery { public: typedef std::vector<std::string>::size_ty