您的位置:首页 > 编程语言 > C语言/C++

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

2014-12-28 12:26 691 查看
//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;

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: