日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ 容器的综合应用的一个简单实例——文本查询程序

發布時間:2025/3/20 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 容器的综合应用的一个简单实例——文本查询程序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[0. 需求]

最近在粗略學習《C++ Primer 4th》的容器內容,關聯容器的章節末尾有個很不錯的實例。
通過實現一個簡單的文本查詢程序,希望能夠對C++的容器學習有更深的理解。
由于是淺略探討研究,高手可無視,各位讀者發現有什么不妥的地方,請指教。

程序將讀取用戶指定的任意文本文件,然后允許用戶從該文件中查找單詞。
查詢的結果是該單詞出現的次數,并列出每次出現所在的行。
如果某單詞在同一行中多次出現,程序將只顯示該行一次。
行號按升序顯示,即第 1行應該在第 2 行之前輸出,依此類推。

本人用到的文本文件“ inputfile.txt ”,內容如下(顯示的行號并非文件原內容):

1 Our program will read a file specified by the user and then allow the user to 2 search the file for words that might occur in it. The result of a query will be 3 the number of times the word occurs and a list of lines on which 4 it appears. If a word occurs more than once on the same line, 5 our program should be smart enough to display that line only once. 6 Lines should be displayed in ascending orderthat is, 7 line 7 should be displayed before line 9, and so on.

[1. 程序的設計]

設計程序的一個良好習慣是首先將程序所涉及的操作列出來。
這樣有助于建立需要的數據結構和實現這些行為。

本程序的需求如下:
它必須允許用戶指明要處理的文件名字。
程序將存儲該文件的內容,以便輸出每個單詞所在的原始行。
它必須將每一行分解為各個單詞,并記錄每個單詞所在的所有行。
在輸出行號時,應保證以升序輸出,并且不重復。
對特定單詞的查詢將返回出現該單詞的所有行的行號。
輸出某單詞所在的行文本時,程序必須能根據給定的行號從輸入文件中獲取相應的行。

1.1 數據結構

我們將用一個簡單的類 TextQuery ,再配合幾種容器的使用,實現這個程序的要求。
使用一個 vector<string> 類型的對象存儲整個輸入文件的副本。
輸入文件的每一行是該 vector 對象的一個元素。
因而,在希望輸出某一行時,只需以行號為下標獲取該行所在的元素即可。
將每個單詞所在的行號存儲在一個 set 容器對象中。
使用 set 就可確保每行只有一個條目,而且行號將自動按升序排列。
使用一個 map 容器將每個單詞與一個 set 容器對象關聯起來,該 set 容器對象記錄此單詞所在的行號。

綜上所述,我們定義的 TextQuery 類將有兩個數據成員:
1. 儲存輸入文件的 vector 對象;
2. map 容器對象(其關聯每個輸入的單詞和記錄該單詞所在行號的 set 容器對象)。

1.2 操作

對于類還要求有良好的接口。
查詢函數需返回存儲一組行號的 set 對象。這個返回類型應該如何設計呢?
事實上,查詢的過程相當簡單:使用下標訪問 map 對象獲取關聯的 set 對象即可。

唯一的問題是如何返回所找到的 set 對象。安全的設計方案是返回該 set 對象的副本。
但如此一來,就意味著要復制 set 中的每個元素。
如果處理的是一個相當龐大的文件,則復制 set 對象的代價會非常昂貴。
其他可行的方法包括:
返回一個 pair 對象,存儲一對指向 set 中元素的迭代器;或者返回 set 對象的 const 引用。

為簡單起見,我們在這里采用返回副本的方法,
但注意:如果在實際應用中復制代價太大,需要新考慮其實現方法。

類的接口需提供下列三個 public 函數:
1. read_file 成員函數,其形參為一個 ifstream& 類型對象。
  該函數每次從文件中讀入一行,并將它保存在 vector 容器中。
  輸入完畢后,read_file 將創建關聯每個單詞及其所在行號的 map 容器。

2. run_query 成員函數,其形參為一個 string 類型對象,返回一個 set 對象,
  該 set 對象包含出現該 string 對象的所有行的行號。

3. text_line 成員函數,其形參為一個行號,返回輸入文本中該行號對應的文本行。
  無論 run_query 還是 text_line 都不會修改調用此函數的對象,
  因此,可將這兩個操作定義為 const 成員函數。
  為實現 read_file 功能,還需定義兩個 private 函數來讀取輸入文本和創建 map 容器:

4. store_file 函數讀入文件,并將文件內容存儲在 vector 容器對象中。

5. build_map 函數將每一行分解為各個單詞,創建 map 容器對象,同時記錄每個單詞出現的行號。

[2. TextQuery 類]

定義 TextQuery 類的頭文件 “ TextQuery.h ” 內容如下:

#ifndef __TEXTQUERY_H__ #define __TEXTQUERY_H__#include <iostream> #include <istream> #include <fstream> #include <vector> #include <map> #include <set> #include <utility> #include <string>typedef std::vector<std::string>::size_type line_no;class TextQuery {public:// interface: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:// utility functions used by read_filevoid store_file(std::ifstream&);void build_map(); // associate each word with a set of line numbers// remember the whole input filestd::vector<std::string> lines_of_text;// map word to set of the lines on which it occursstd::map< std::string, std::set<line_no> > word_map; };#endif

注意:這個類的定義中,在引用標準庫內容時都必須完整地使用 std:: 限定符。

read_file 函數在類的內部定義。該函數首先調用 store_file 讀取并保存輸入文件,
然后調用 build_map 創建關聯單詞與行號的 map 容器。

[3. TextQuery 類的使用]

下面的主程序 main 使用 TextQuery 對象實現簡單的用戶查詢會話。
這段程序的主要工作是實現與用戶的互動:
提示輸入下一個要查詢的單詞,然后調用 print_results 函數輸出結果。

3.1 引子

程序首先檢查 argv[1] 是否合法,然后調用 open_file 函數打開以 main 函數實參形式給出的文件。
檢查流以判斷輸入文件是否正確。
如果不正確,就給出適當的提示信息結束程序的運行,返回 EXIT_FAILURE 說明發生了錯誤。
一旦文件成功打開,建立支持查詢的 map 容器就相當簡單。

open_file 函數的實現如下:

// opens in binding it to the given file ifstream& open_file(ifstream &in, const string &file) {in.close(); // close in case it was already openin.clear(); // clear any existing errors// if the open fails, the stream will be in an invalid statein.open(file.c_str()); // open the file we were givenreturn in; // condition state is good if open succeeded }

3.2 實現查詢

為了使用戶在每次會話時都能查詢多個單詞,我們將提示語句也置于 while 循環中:

#include "TextQuery.h"define EXIT_FAILURE -1using namespace std;int main(int argc, char *argv[]) {// open the file from which user will quer words ifstream infile;if(argc < 2 || !open_file(infile, argv[1])){cerr << "No input file!" << endl;return EXIT_FAILURE;}TextQuery tq;tq.read_file(infile);// prompt for a word to file and print resultwhile(true){cout << "Enter word to look for(or Q/q to Quit): \n" ;string str;cin >> str;// stop if hit eof on input or a 'Q' is entered if(!cin || str == "Q" || str == "q")break;// get tje set of line numbers on which this word appearsset<line_no> locs = tq.run_query(str);// print count an all occurrences, if any print_results(locs, str, tq);}return 0; }

while 循環條件為布爾字面值 true,這就意味著循環條件總是成立。
在檢查 cin 和讀入 s 值后,由緊跟的 break 語句跳出循環。
具體說來,當 cin 遇到錯誤或文件結束,或者用戶輸入 q 時,循環結束。
每次要查找一個單詞時,訪問 tq 獲取記錄該單詞出現的行號的 set 對象。
將 set 對象、要查找的單詞和 TextQuery 對象作為參數傳遞給 print_results 函數,該函數輸出查詢結果。

3.3 輸出結果

輸出時,首先給出查詢到的匹配個數,即 set 對象的大小。
然后調用一個 make_plural 函數,根據 size 是否為 1 輸出“time”或“times”。

// return plural version of word if ctr isn't 1 string make_plural(size_t ctr, const string &word,const string &ending) {return (ctr == 1) ? word : word + ending; } void print_results(const set<line_no>& locs, const string& sought, const TextQuery& file) {// if the word was found, then print count and all occurrencestypedef set<line_no> line_nums;line_nums::size_type size = locs.size();cout << "\n" << sought << " occurs " << size << " "<< make_plural(size, "time", "s") << endl;// print each line in which the word appearedline_nums::const_iterator it = locs.begin();for(; it != locs.end(); ++it){// don't confound user with text lines starting at 0cout << "\t(line" << (*it) +1 << ")" << file.text_line(*it) << endl;} }

?

以上幾個函數定義和實現都放在 main.cpp 文件之中。

注意:為了與 C++ 的容器和數組下標編號匹配,在儲存文本時,我們以行號 0 存儲第一行。
但考慮到很多用戶會默認第一行的行號為 1,所以輸出行號時,
相應地所存儲的行號上加 1 使之轉換為更通用的形式。

[4. 成員方法的實現]

TextQuery 類的成員方法實現 “ TextQuery.cpp” 文件內容如下:

#include "TextQuery.h" #include <stdexcept> #include <sstream>using namespace std;set<line_no> TextQuery::run_query(const string &query_word) const {// must use find and not subscript he map directly// to avoid adding words to word_mapmap< string, set<line_no> >::const_iteratorloc = word_map.find(query_word);if(loc == word_map.end()){// not found, return empty setreturn set<line_no>(); }else{// fectch and return set of line numbers for this wordreturn loc->second; } }string TextQuery::text_line(line_no line) const {if(line < lines_of_text.size())return lines_of_text[line];throw std::out_of_range("line number out of range"); }// utility functions used by read_file void TextQuery::store_file(ifstream &is) {string textline;while (getline(is, textline))lines_of_text.push_back(textline); }// associate each word with a set of line numbers void TextQuery::build_map() {// process each line from the input vectorfor (line_no line_num = 0; line_num != lines_of_text.size(); ++line_num) {// we'll use line to read the text a word at a time istringstream line(lines_of_text[line_num]);string word;while (line >> word){// add this line number to the set;// subscript will add word to the map if it's not already there word_map[word].insert(line_num);}} }

[5. 編譯運行]

之前一直是用 CFree5.0 做的《C++ Primer 4th》的練習,
但是由于沒找到怎么手動添加參數運行程序,
>_<|||...有知道怎么搞的,還望不吝賜教。
沒辦法最后選了在 cygwin 下編譯,命令如下:

編譯成功后,文件如下:

運行,命令如下:

結果顯示如下:

根據運行結果觀察,應該是實現了預期的程序功能。O(∩_∩)O 哈哈~

轉載于:https://www.cnblogs.com/yshl-dragon/p/3152803.html

總結

以上是生活随笔為你收集整理的C++ 容器的综合应用的一个简单实例——文本查询程序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜电影天堂 | 欧美超碰在线观看 | 神马午夜av | 麻豆精品国产传媒mv男同 | 日韩精品视频一区二区三区 | 久久久久久国产精品免费播放 | 97播播 | 啪啪av| 国产激情一区二区三区在线观看 | 操www | 影音先锋中文字幕一区二区 | 最新久久 | 2019天天操 | 国产亚洲女人久久久久毛片 | 中文在线一区二区三区 | 极度诱惑香港电影完整 | 欧美一区二区 | 国产精品欧美综合亚洲 | 精品亚洲一区二区三区 | 国产激情视频一区二区 | 国产最新毛片 | 熊出没之冬日乐翻天免费高清观看 | 亚洲国产欧美在线观看 | 26uuu国产| 99精品欧美一区二区三区综合在线 | 小宵虎南在线观看 | 一区二区视频免费 | 五月综合激情网 | 天天干,夜夜爽 | 国产91大片 | 色天堂视频 | 国产 日韩 欧美 成人 | 成人免费高清在线播放 | 少妇天堂网 | 精品无码人妻一区二区三区 | 噜噜噜在线视频 | 五月天婷婷导航 | 久久视频网 | 国产xxxx性hd极品 | 自拍偷拍小视频 | 免费国产在线视频 | 欧美黄色a视频 | 欧美黑人xxxⅹ高潮交 | 性高潮影院 | 国产精品自拍一区 | 小情侣高清国产在线播放 | 天天躁日日躁aaaaxxxx | 精品少妇3p | 日韩欧美在线视频观看 | 自拍偷拍亚洲天堂 | 国产一级大片 | 日韩三级黄 | 国产一区二区在线看 | 秋霞福利片| 亚洲中文字幕无码av永久 | 日韩操操| 国产精品123区 | 国产91香蕉 | 亚洲免费看黄 | 污夜影院| 亚洲免费在线观看视频 | 黄色在线免费网站 | 双乳被四个男人吃奶h文 | 国产黄av | 在线观看高清av | 亚洲色图 在线视频 | 国产女大学生av | 污到下面流水的视频 | 私拍在线 | 伊人久久天堂 | 美女av免费看 | 国产精品一区不卡 | 在线观看免费黄色小视频 | 无码人妻一区二区三区在线视频 | 精品在线免费视频 | 美女黄视频在线观看 | 在线天堂网 | 国产一级免费av | 91麻豆精品 | 小情侣高清国产在线播放 | 日韩性xx | 欧美在线黄 | 国内露脸中年夫妇交换 | 国产中文字幕乱人伦在线观看 | 天天做夜夜做 | 日韩一级在线观看视频 | www.av88| 在线观看香蕉视频 | 97黄色网| 激情网页 | 青青草原在线免费 | 欧美在线一二三区 | 99re在线精品视频 | 亚洲天堂少妇 | 国产精品videos | 日韩有码电影 | 都市乱淫 | 亚洲第一区av | 欧美色婷婷 |