zoukankan      html  css  js  c++  java
  • C++自学笔记_文本查询程序_《C++ Primer》

    《C++ Primer》 第10章结束,用一个文本查询程序结束本章 :)

    程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词。查询的结果是该单词出现的次数,并列出每次出现所在的行。如果某单词在同一行

    中多次出现,程序将只显示该行一次。行号按照升序显示。

    程序支持以下任务:

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

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

      · 对特定单词的查询将返回出现该单词的所有行的行号。

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

    假定要查询的文件路径为  F:C++ Primer_TXTTextQuery.txt

    TextQuery.txt:

    Code:
    #include <iostream>
    #include <vector>
    #include <map>
    #include <set>
    #include <fstream>
    #include <sstream>
    #include <stdexcept>
    
    using namespace std;
    
    class TextQuery{
    public:
        typedef vector<string>::size_type line_no;
        void read_file(ifstream &is){
            store_file(is);
            build_map();
        }
        set<line_no> run_query(const string&) const;
        string text_line(line_no) const;
    private:
        void store_file(ifstream &);
        void build_map();
        vector<string> lines_of_text;
        map<string,set<line_no> >word_map;
    };
    
    /*存储输入文件*/
    void TextQuery::store_file(ifstream &is){
        string textline;
        while(getline(is,textline)){
            lines_of_text.push_back(textline);
        }
    }
    
    /*建立map容器*/
    void TextQuery::build_map(){
        for(line_no line_num=0;line_num!=lines_of_text.size();++line_num){
            istringstream line(lines_of_text[line_num]);
            string word;
            while(line>>word){
                word_map[word].insert(line_num);
            }
        }
    }
    
    /*支持查询*/
    set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const{
        map<string,set<line_no> >::const_iterator loc=word_map.find(query_word);
        if(loc==word_map.end())
            return set<line_no>();
        else
            return loc->second;
    }
    
    /*run_query返回值的使用*/
    string TextQuery::text_line(line_no line) const{
        if(line<lines_of_text.size())
            return lines_of_text[line];
        else
            throw out_of_range("line number out of range");
    }
    
    string make_plural(TextQuery::line_no ctr,const string &word,const string &ending){
        return (ctr==1)? word:word+ending;
    }
    
    void print_results(const set<TextQuery::line_no>& locs,const string& sought,const TextQuery &file){
        typedef set<TextQuery::line_no> line_nums;
        line_nums::size_type size=locs.size();
        cout<<"
    "<<sought<<" occurs "<<size<<make_plural(size," time","s")<<endl;
        line_nums::const_iterator it=locs.begin();
        for( ;it!=locs.end();++it){
            cout<<"	(line "<<(*it)+1<<") "<<file.text_line(*it)<<endl;
        }
    }
    
    int main()
    {
        ifstream infile;
        cout<<"enter a file path to query: ";
        string fileName;
        getline(cin,fileName);
        infile.open(fileName.c_str());
        TextQuery tq;
        tq.read_file(infile);
        while(true){
            cout<<endl<<"enter a word to look for,or q to quit: ";
            string str;
            cin>>str;
            if(!cin||str=="q")
                break;
            set<TextQuery::line_no> locs=tq.run_query(str);
            print_results(locs,str,tq);
        }
        return 0;
    }

  • 相关阅读:
    离奇的软件开发之路
    集群环境中的单例设计模式
    Android 如何更换屏幕上锁界面背景图片
    基于华为Java编程规范的Eclipse checkStyle.xml
    对数据库事务的总结
    [Sciter系列] MFC下的Sciter–1.创建工程框架
    Android 如何添加一种锁屏方式
    Hibernate级联操作 注解
    linux就是这个范儿之融于心而表于行(1)
    Android 如何修改默认的searchable items。
  • 原文地址:https://www.cnblogs.com/Murcielago/p/4164863.html
Copyright © 2011-2022 走看看