C++ Primer 关联容器--容器的综合应用:文本查询程序

来源:互联网 发布:淘宝微博 编辑:程序博客网 时间:2024/06/06 05:49
//TextQuery.h  
#ifndef _TEXTQUERY_H_  
#define _TEXTQUERY_H_  
  
#include <vector>  
#include <fstream>  
#include <iostream>  
#include <string>  
#include <set>  
#include <map>  
  
class TextQuery{  
public:  
    typedef std::vector<std::string>::size_type line_no;  
    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:  
    void store_file(std::ifstream&);  
    void build_map();  
    std::vector<std::string> lines_of_text;  
    std::map< std::string, std::set<line_no> > word_map;  
};  
  

#endif 

// textQuery.cpp : 定义控制台应用程序的入口点。


#include "stdafx.h"
#include "textquery.h"  
#include <iostream>  
#include <sstream>  
#include <utility>  
using std::string;  
using std::vector;  
using std::set;  
using std::map;  
using std::istringstream;  
  
  
std::set<TextQuery::line_no> TextQuery::run_query(const std::string &word) const  
{  
    map< string, set<line_no> >::const_iterator iter = word_map.find(word);  
    if (iter != word_map.end())  
    {  
        return iter->second;  
    }  
    else  
    {  
        set<line_no> temp;  
        return temp;  
        //return set<line_no>();//书上使用这种方法,简明了许多  
    }     
}  
  
std::string TextQuery::text_line(line_no linenumber) const  
{  
    return lines_of_text[linenumber];  
}  
  
void TextQuery::store_file(std::ifstream &is)  
{  
    string line;  
    while (getline(is, line))  
    {  
        lines_of_text.push_back(line);        
    }  
  
}  
  
  
void TextQuery::build_map()  
{  
    string word;  
    map< string, set<line_no> >::iterator iter;  
    for (line_no ix = 0; ix != lines_of_text.size(); ++ix)  
    {  
        istringstream stream(lines_of_text[ix]);  
        //istringstream stream;  
        //stream.str(lines_of_text[ix]);//有两种将string转换为istringstream的方法  
        while (stream >> word)  
        {  
            //word_map[word].insert(ix);//书上用了这种写法,只需一句简单明了多了  
            iter = word_map.find(word);  
            if (iter != word_map.end())  
            {  
                iter->second.insert(ix);  
            }  
            else  
            {  
                set<line_no> lineset;  
                lineset.insert(ix);  
                word_map.insert(make_pair(word, lineset));  
            }  
        }  
    }  
      
}  

//test.cpp  

#include"stdafx.h"
#include "textquery.h"  
#include <iostream>  
#include <string>  
#include <set>  
#include <fstream>  
#include <utility>  
  
using std::ifstream;  
using std::cerr;  
using std::cout;  
using std::cin;  
using std::string;  
using std::endl;  
using std::set;  
using std::runtime_error;  
  
  
ifstream& open_file(ifstream& in, const string& file)    
{    
    in.close();    
    in.clear();    
    in.open(file.c_str());    
    return in;    
}   
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 << "\n" << sought << " occurs "  
            << size << " "  
            << "times" << endl;  
    line_nums::const_iterator iter = locs.begin();  
    for ( ; iter != locs.end(); ++iter)  
    {  
        cout << "\t(line "   
                << (*iter) + 1 << ") "  
                << file.text_line(*iter) << endl;  
    }  
}  
  
int main(int argc, char **argv)  
{  
    /*下面两种文件的读取方式均可。运行程序有两种方法 
    方法一:利用cmd命令到命令行窗口,进入到可执行文件所在的目录 
    输入xxx.exe yyy.txt 
    方法二:利用vs2008属性-调试-命令参数中填写yyy.txt 
    然后在工作目录中填写可执行程序所在目录,将yyy.txt也放入此目录中 
    要注意的是对于win7系统,文件名后缀是不显示的,所以在命名文件时 
    不需要写yyy.txt,这样会出现文件全名变成yyy.txt.txt的情况*/  
#if 0  
    ifstream infile;  
    if (argc < 2 || !open_file(infile, argv[1]))  
    {  
        cerr << "No input file!" << endl;  
        //return EXIT_FAILURE;  
    }  
    //open_file(infile, argv[1]);  
#endif  
#if 1  
    if (argc != 2)  
    {  
        throw runtime_error("wrong number of arguments");  
    }  
    ifstream infile;  
    if (!open_file(infile, argv[1]))  
    {  
        throw runtime_error("no input file");  
    }  
#endif  
    TextQuery tq;  
    tq.read_file(infile);  
    while (true)  
    {  
        cout << "enter word to look for, or q to quit: ";  
        string s;  
        cin >> s;  
        if (!cin || s == "q")  
        {  
            break;  
        }  
        set<TextQuery::line_no> locs = tq.run_query(s);  
        print_results(locs, s, tq);  
    }  
    return 0;  
}  



0 0
原创粉丝点击