C++ primer 第12章 12.3 使用標準庫:文本查詢程序

文章目錄

  • 使用標準庫:文本查詢程序
    • 文本查詢程序設計
      • 數據結構
      • 在類之間共享數據
      • 自己的文本查詢程序
      • 書中的文本查詢程序

使用標準庫:文本查詢程序

我們將實現一個簡單的文本查詢程序,作為標準庫相關內容學習的總結。

我們的程序允許用戶在一個給定文件中查詢單詞。查詢結果是單詞在文件中出現的次數及其所在行的列表。如果一個單詞在一行中出現多次,此行只列出一次。行會按照升序輸出。

文本查詢程序設計

在這里插入圖片描述

數據結構

我們定義一個保存輸入文件的類,將這個類命名為TextQuery,它包含一個vector和一個map。vector用來保存輸入文件的文本,map用來關聯每個單詞和它出現的行號的set。這個類將會有一個用來讀取給定輸入文件的構造函數和一個執行查詢的操作。
在這里插入圖片描述

在類之間共享數據

在這里插入圖片描述

自己的文本查詢程序

TextQuery類

#ifndef __TEXTQUERY__
#define __TEXTQUERY__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
#include<fstream>
#include<sstream>
#include"QueryResult.h"
using namespace std;class TextQuery {
public:TextQuery() {}TextQuery(ifstream &ifs);QueryResult query(string & s);
private:shared_ptr<vector<string>>strText;shared_ptr<map<string,set<int>>>strNum;
};TextQuery::TextQuery(ifstream &ifs) {string str;vector<string>vec;while (getline(ifs, str)) {vec.push_back(str);}strText = make_shared<vector<string>>(vec);map<string, set<int>>mp;int LineNum = 1;for (auto a : *strText) {istringstream vecStr(a);string tmp;while (vecStr >> tmp) {mp[tmp].insert(LineNum);}LineNum++;}strNum = make_shared<map<string, set<int>>>(mp);cout << "success1"<<endl;
}QueryResult TextQuery::query(string & s) {if (strNum->find(s) == strNum->cend()) {return QueryResult(s, 0, strText, strNum);}int num = (strNum->at(s)).size();cout << "num:"<<num << endl;return QueryResult(s,num, strText, strNum);
}#endif

QueryResult類

#ifndef __QUERYRESULT__
#define __QUERYRESULT__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
using namespace std;class QueryResult {
public:QueryResult() {}QueryResult(string&s,int num,shared_ptr<vector<string>>strText, shared_ptr<map<string, set<int>>>strNum):str(s),nums(num),strText(strText),strNum(strNum){}string getStr() { return str; }int getNums() { return nums; }shared_ptr<vector<string>> getStrText() { return strText; }shared_ptr<map<string, set<int>>>getStrNum() { return strNum; }
private:string str;int nums;shared_ptr<vector<string>>strText;shared_ptr<map<string, set<int>>>strNum;
};ostream & print(ostream &os, QueryResult &qr) {if (qr.getNums() == 0) {os << qr.getStr() << " occurs " << qr.getNums() << " time" << endl;return os;}os << qr.getStr() << " occurs " << qr.getNums() << (qr.getNums() > 1 ? "times" : "time") << endl;shared_ptr<map<string, set<int>>> mp = qr.getStrNum();shared_ptr<vector<string>>vec = qr.getStrText();set<int>st=mp->at(qr.getStr());for (auto n:st) {os << "(line" << n << ")" << vec->at(n-1) << endl;}return os;}#endif

測試程序:

void testTextQuery() {ifstream infile("test.txt");TextQuery tq(infile);while (true) {cout << "enter word to look for,or q tu quit:"<<endl;string s;if (!(cin >> s) || s == "q")break;print(cout, tq.query(s)) << endl;}
}

書中的文本查詢程序

TextQuery類

#ifndef __TEXTQUERY__
#define __TEXTQUERY__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
#include<fstream>
#include<sstream>
#include"QueryResult.h"
using namespace std;class TextQuery {
public:using line_no = vector<string>::size_type;TextQuery() {}TextQuery(ifstream &ifs);QueryResult query(const string & s)const;
private:shared_ptr<vector<string>>strText;map<string, shared_ptr<set<line_no>>>strNum;
};TextQuery::TextQuery(ifstream &ifs):strText(new vector<string>) {string str;while (getline(ifs, str)) {strText->push_back(str);int n = strText->size() - 1;istringstream vecStr(str);string word;while (vecStr >> word) {auto &lines = strNum[word];//lines是一個shared_ptrif (!lines)//在我們第一次遇到這個單詞時,此指針為空lines.reset(new set<line_no>);//分配一個新的setlines->insert(n);}}
}QueryResult TextQuery::query(const string & s)const {static shared_ptr<set<line_no>>nodata(new set<line_no>);if (strNum.find(s) == strNum.cend()) {return QueryResult(s,strText, nodata);}elsereturn QueryResult(s,strText, strNum.find(s)->second);
}#endif

QueryResult類

#ifndef __QUERYRESULT__
#define __QUERYRESULT__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
using namespace std;class QueryResult {friend ostream& print(ostream &os, const QueryResult &qr);
public:using line_no = vector<string>::size_type;QueryResult() {}QueryResult(const string&s,shared_ptr<vector<string>>strText, shared_ptr<set<line_no>>strNum):str(s),strText(strText),strNum(strNum){}private:string str;shared_ptr<vector<string>>strText;shared_ptr<set<line_no>>strNum;
};ostream & print(ostream &os, const QueryResult &qr) {os << qr.str << " occurs " << qr.strNum->size()<< (qr.strNum->size() > 1 ? " times" : " time") << endl;for (auto n:*qr.strNum) {os << "\t(line" << n+1 << ")" << qr.strText->at(n) << endl;}return os;}#endif

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446552.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446552.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446552.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言二維數組 int arr[2][3]

基礎使用 先遍歷行再遍歷列 #include<stdio.h> //二維數組的基本使用 int main() {//二維數組的初始化int arr1[2][2]{{2,2},{0,0}};int arr2[2][3]{2,2,2,8,8,8};int arr3[6][9];int i,j;for(i0;i<6;i){for(j0;j<9;j){arr3[i][j]1;}}arr3[2][5]0;//打印printf(&…

牛客網C++面經 類和數據抽象

請你來說一下C中struct和class的區別 在C中&#xff0c;可以用struct和class定義類&#xff0c;都可以繼承。區別在于&#xff1a;structural的默認繼承權限和默認訪問權限是public&#xff0c;而class的默認繼承權限和默認訪問權限是private。另外&#xff0c;class還可以定義…

C++ primer 第13章 拷貝控制

文章目錄前言拷貝、賦值與銷毀拷貝構造函數合成拷貝構造函數拷貝初始化和直接初始化拷貝初始化的發生&#xff1a;參數和返回值拷貝初始化的限制拷貝賦值運算符重載賦值運算符合成拷貝賦值運算符析構函數析構函數完成的工作什么時候會調用析構函數合成析構函數代碼片段調用幾次…

C語言 指針自增自減加減運算 p++ p+i

介紹 自增自減代碼 #include<stdio.h> #include<string.h> //指針自增--short void increase(short *arr,int len) {int i;arr&arr[0];for(i0;i<len;i){printf("arr[%d]%d,address%p\n",i,*arr,arr);arr;} }//指針自減--char void decrease(char…

C++ 編譯與底層

原文鏈接 編譯與底層請你來說一下一個C源文件從文本到可執行文件經歷的過程&#xff1f; 對于C源文件&#xff0c;從文本到可執行文件一般需要四個過程&#xff1a;預處理階段&#xff1a;對源代碼文件中文件包含關系&#xff08;頭文件&#xff09;、預編譯語句&#xff08;…

C語言 指針數組-字符指針數組整型指針數組 char*s[3] int*a[5] 數組指針int(*p)[4]

基本介紹 1.指針數組:由n個指向整型元素的指針而組成,里面存放指針 Int *ptr[3]; 2.地址: ptr[i]:元素地址 &ptr[i]:指針地址 圖示 代碼: 內存布局: 代碼 #include<stdio.h> #include<string.h> //指針數組--int void pointer(int *arr,int len) {int …

uninitialized_copy測試代碼示例

原測試代碼如下&#xff1a; int main() {vector<int>v1{1,3,5,7,9,2,4,6,8};allocator<int>alloc;auto data alloc.allocate(9);uninitialized_copy(v1.begin(),v1.end(), data);auto end data 9;while(data!end) {cout << *data <<" "…

C語言的地址 內存

取地址在CPU的寄存器產生&#xff0c;不占據內存地址由計算器總線&#xff0c;地址作為常量不消耗內存指針 存儲不同的地址&#xff0c;間接賦值空類型指針 void* 類型指針 不可以取數據 或者修改數據 需要進行強制類型轉換int num 10;void *p &num;std::cout << …

C語言 多重指針--整型字符字符串 int**pp

介紹 多重指針:一個指針指向另一個指針 離值越近的指針級別越大:一級 內存布局 代碼 圖示: 多重指針–整型 #include<stdio.h> #include<string.h> //多重指針--整型//二級指針 void two() {printf("二級指針:\n");int a896;int *p&a,**pp&…

C++ primer 第13章 拷貝控制

文章目錄前言拷貝、賦值與銷毀拷貝構造函數合成拷貝構造函數拷貝初始化和直接初始化拷貝初始化的發生&#xff1a;參數和返回值拷貝初始化的限制拷貝賦值運算符重載賦值運算符合成拷貝賦值運算符析構函數析構函數完成的工作什么時候會調用析構函數合成析構函數代碼片段調用幾次…

牛客網C++面經 C++11

請問C11有哪些新特性&#xff1f; auto關鍵字&#xff1a;編譯器可以根據初始值自動推導出類型。但是不能用于函數傳參以及數組類型的推導nullptr關鍵字&#xff1a;nullptr是一種特殊類型的字面值&#xff0c;它可以被轉換成任意其它的指針類型&#xff1b;而NULL一般被宏定義…

C語言 返回指針的函數--指針函數 int* max(int a)

定義 strlong示例代碼 代碼1: #include<stdio.h> #include<string.h> //返回指針的函數//比較兩個字符串,返回更長的字符串 char *strlong(char* a,char* b) {char *p1&a[0];char *p2&b[0];while(true){if(*p1\0){return b;}else if(*p2\0){return a;}p1…

第2、3講 圖像的存儲格式

本圖像處理系列筆記是基于B站楊淑瑩老師的課程進行學習整理的。 文章目錄黑白圖像8位灰度索引圖像8位偽彩色索引圖像24位真彩色圖像圖像文件格式BMP文件存儲格式BMP文件頭位圖信息頭顏色表位圖信息——BITMAPINFO結構BMP位圖文件匯總按照顏色深度分類&#xff0c;常用圖像文件&…

Ubuntu18.04.4 環境下對屬性加密算法CP-ABE環境搭建

注意事項 cpabe依賴pbc&#xff0c;pbc依賴gmp&#xff0c;gmp依賴M4、bison、flex如果權限不夠 &#xff0c;命令的前面加上sudo &#xff0c;不要直接使用root用戶進行操作&#xff0c;其帶來的隱患有很多 第一步 配置簡單的環境 簡單環境 包括gcc、g、make、cmake、openss…

C語言 函數指針 int(*ptr)(int,int)

基本介紹 函數指針:指向函數的指針 與數組類似 定義 Int(*pmax)(int ,int)max; Int(*pmax)(int x,int y)max;//形參名稱不重要 函數返回類型(*指針)(形參類型)函數名稱; 具體案例 代碼: *pmax取到函數本身 調用函數指針方式: (*pmax)(x,y); pmax(x,y);//與java中調用函數一…

C++ primer 第14章 操作重載與類型轉換

文章目錄基本概念直接調用一個重載的運算符函數某些運算符不應該被重載使用與內置類型一致的含義選擇作為成員或者非成員輸入和輸出運算符重載輸出運算符<<輸出運算符盡量減少格式化操作輸入輸出運算符必須是非成員函數重載輸入運算符>>算術和關系運算符相等運算符…

C語言 回調函數 produce(arr,len,getRand)

基本介紹 回調函數:形參中包含另一個函數的函數指針 用函數指針接收另一個函數 案例 代碼解析 具體代碼 #include<stdio.h> #include<stdlib.h> //回調函數--//函數原型 int getRand(); int *produce(int*arr,int len,int(*get)()); int main() {int arr[10…

從零開始配置服務器密碼機的開發環境

開發環境環境配置安裝gcc編譯器安裝g編譯器安裝make安裝cmake安裝ssh安裝git和配置安裝大文件管理工具git-lfs安裝數據庫sqlite3安裝數據庫sqlite_orm文件安裝Openssl安裝Tcl和Tk安裝tcl-expect-dev安裝boost安裝clang-format安裝Clion注意事項安裝automake和libudev-dev環境配…

C語言 動態內存分配機制(堆區) int*p=malloc(5*sizeof(4))

C程序內存分配圖 棧區:局部變量 堆區:動態分配的數據 靜態存儲區/全局區:全局變量,靜態數據 代碼區:代碼,指令 內存分配說明 內存動態分配的相關函數 堆區: #inlcude<stdlib.h> Malloc(size);//分配長度為size個字節的連續空間 Calloc(n,size);//分配size個長度為n…

C++ primer 第15章 面向對象程序設計

文章目錄前言OOP&#xff1a;概述繼承動態綁定定義基類和派生類定義基類成員函數與繼承訪問控制與繼承定義派生類派生類中的虛函數派生類對象及派生類向基類的類型轉換派生類構造函數派生類使用基類的成員繼承與靜態成員派生類的聲明被用作基類的類防止繼承的發生類型轉換與繼承…