文本查询程序
目的:熟悉各種關聯容器的使用以及面向具體任務時程序的設計流程。
參考:c++primer 10.6
基本步驟:用戶需求 -> 明確任務 -> 數據結構以及相關操作 ->定義相關類 ->根據操作定義類成員函數
任務描述:從已知文檔中查詢某個單詞出現的次數,并列出所在行
任務分工:1.需要有一個函數來讀取指定文件,將其存儲在向量中并用一個map記錄每個單詞的所在行,map.first是單詞,map.second 是一個由行號組成的set;
2.需要一個查詢函數,對特定的單詞返回其行號的set;
3.需要一個輸出查詢結果的函數(這個是對外接口,放在主函數中較為合適)。
數據格式的使用:vector非常適合存儲和遍歷;而map能提供方便的查詢接口;set中存儲所在行號的集合保證了唯一性和有序性。
具體代碼如下:
TextQuery.h
#pragma once #include <iostream> #include <string> #include <fstream> #include <vector> #include <sstream> #include <map> #include <set> #include <stdexcept> class TextQuery { public:TextQuery();~TextQuery();typedef std::vector<std::string>::size_type line_no;//為每一行的索引定義一個別名void read_file(std::ifstream & is);//讀取文件 private:void store_file(std::ifstream & is);//這兩個函數對外不可見,被成員函數read_file調用std::vector<std::string> lines_of_text; private:void build_map();//這兩個函數對外不可見,被成員函數read_file調用std::map<std::string, std::set<line_no> > word_map; public:std::set<line_no> run_query(const std::string & query_word);//查詢單詞所在的行號std::string tex_line(line_no line) const;//顯示某行文本內容 };?TextQuery.cpp
#include "TextQuery.h"TextQuery::TextQuery() { }TextQuery::~TextQuery() { }void TextQuery::read_file(std::ifstream & is) {store_file(is);build_map(); }void TextQuery::store_file(std::ifstream & is) {std::string textline;while (getline(is, textline)){lines_of_text.push_back(textline);} }void TextQuery::build_map() {for (line_no line_num = 0; line_num != lines_of_text.size(); line_num++){std::istringstream line(lines_of_text.at(line_num));std::string word;while (line >> word){word_map[word].insert(line_num);}} }std::set<TextQuery::line_no> TextQuery::run_query(const std::string & query_word) {std::map <std::string, std::set<line_no> >::const_iterator loc = word_map.find(query_word);if (loc == word_map.end()){return std::set<line_no>();}else{return loc->second;}}std::string TextQuery::tex_line(line_no line) const {if (line < lines_of_text.size())return lines_of_text.at(line);elsethrow std::out_of_range("line number out of range"); }?main.cpp
#include "TextQuery.h" #include <iostream> #include <stdlib.h> using namespace std;ifstream& open_file(ifstream &in, const string &file) {in.close();in.clear();in.open(file.c_str());return in; } string make_plural(size_t ctr, const string &word, const string &ending) {return (ctr == 1) ? word : word + ending;//處理字符串中單復數輸出的一個函數,7.3.2中有原型 } 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 << " " << make_plural(size, "time", "s") << endl;line_nums::const_iterator it = locs.begin();for (; it != locs.end(); it++){cout << "\t(line" << (*it) << ")" << file.tex_line(*it) << endl;}} int main(int argc,char ** argv) {ifstream infile;if (argc < 2 || !open_file(infile, argv[1])){cerr << "no input file" << endl;return EXIT_FAILURE;//這是C中的一種拋出錯誤的處理}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; }?makefile如下:
edit:main.o TextQuery.og++ -o edit main.o TextQuery.o main.o:main.cpp TextQuery.hg++ -c main.cpp TextQuery.o:TextQuery.cpp TextQuery.hg++ -c TextQuery.cpp clean:rm main.o TextQuery.o?
轉載于:https://www.cnblogs.com/simayuhe/p/5865248.html
總結
- 上一篇: 标签(表的单元素)
- 下一篇: 【NOIP2014】子矩阵