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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

容器的综合应用:文本查询程序

發布時間:2023/12/13 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 容器的综合应用:文本查询程序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

需求

程序讀取用戶指定的任意文本文件,允許用戶從該文件中查找單詞。查詢結果是該單詞出現的次數,并列出每次出現所在行,如果某單詞在同一行中多次出現,程序將只顯示該行一次。行號按升序顯示,即第 7 行應該在第 9 行之前輸出,依此類推。例如,以本章的內容作為文件輸入,然后查找單詞“element”。輸出的前幾行應為:

element occurs 125 times
(line 62) element with a given key.
(line 64) second element with the same key.
(line 153) element |==| operator.
(line 250) the element type.
(line 398) corresponding element.
后面省略了大約 120 行。

?

看著書上的例子,自己寫了下,大致思路是

讀取文件,將文件以行為單位,放入vector<string>,再遍歷vector<string>,將每行每個單詞讀入map< string,set<unsigned> >中,最后從map中查找讀取

?

注意的地方

程序是不區分大小寫的,還需要去掉文章中的標點需要調用函數

頭文件#include<cctype>

ispunct() 檢查是否是非空格、非數字和非英文字母,類似函數isspace,isdigit,isalpha

tolower() 把字符轉換成小寫字母

對const成員的迭代器需要用const_iterator

?

對于內置類型,和長度比較短(8字節以內)的淺層結構,類等對象,傳值比傳引用效率更高。

對超過8字節的對象,一般傳引用效率更高。

但實際上傳引用或傳值的選擇,主要取決于功能需求而非效率需求。

?

詳解

獲取文件對象:

1 ifstream& open_file(ifstream &in,const string &file) 2 { 3 in.close(); 4 in.clear(); 5 in.open(file.c_str()); 6 return in; 7 }

?

讀文件,創建vector和map

1 void TextQuery::read_file(ifstream &in) 2 { 3 store_file(in); 4 build_map(); 5 } 6 7 void TextQuery::store_file(ifstream &in) 8 { 9 string textline; 10 while(getline(in,textline)) 11 lines_of_text.push_back(textline); 12 } 13 14 void TextQuery::build_map() 15 { 16 for(line_no line_num = 0;line_num != lines_of_text.size();line_num++) 17 { 18 istringstream line(lines_of_text[line_num]); 19 string word; 20 while(line >> word) 21 { 22 word = cleanup_str(word); 23 word_map[word].insert(line_num); 24 } 25 26 } 27 }

?

處理單詞中的符號,忽略大小寫

1 string TextQuery::cleanup_str(const string &word) 2 { 3 string ret; 4 for(string::const_iterator it = word.begin();it != word.end();++it) 5 { 6 if(!ispunct(*it)) 7 ret += tolower(*it); 8 } 9 return ret; 10 }

?

查找單詞,返回值是map的第二個元素set,用來保存單詞所在的行號

1 set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const 2 { 3 map< string,set<line_no> >::const_iterator loc = word_map.find(query_word); 4 if( loc == word_map.end() ) 5 return set<line_no>(); //找不到返回空的set對象 6 else 7 return loc ->second; 8 }

?

返回查找結果,這里有個漏洞,查找單詞的數目是為單詞所出現的行數(因為set不存儲重復元素)

void TextQuery::print_result(set<line_no> locs,const string &query_word) {cout<<query_word<<":"<<locs.size()<<endl;set<line_no>::iterator it = locs.begin();while(it != locs.end()){cout<<"(line "<<*it+1<<") ";cout<<lines_of_text[*it]<<endl;it++;} }

?

寫了兩個輔助函數,并未調用,為了查看vector和map中的內容

1 void TextQuery::show_vec() 2 { 3 vector<string>::iterator ite = lines_of_text.begin(); 4 while(ite != lines_of_text.end()) 5 cout<<*ite++<<endl; 6 } 7 void TextQuery::show_map() 8 { 9 map< string,set<line_no> >::iterator loc = word_map.begin(); 10 while(loc != word_map.end()) 11 { 12 cout<<loc->first<<"\t"; 13 set<line_no>::iterator it = (loc->second).begin(); 14 while(it != (loc->second).end()) 15 { 16 cout<<*it + 1<<" "; 17 it++; 18 } 19 cout<<endl; 20 loc++; 21 } 22 }

運行結果

?

代碼點此下載

轉載于:https://www.cnblogs.com/raichen/p/4900308.html

總結

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

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