C 標準庫 六 使用標準庫 文字查詢程式

2021-10-09 15:03:57 字數 3834 閱讀 4112

本文為《c++ primer》的讀書筆記

文字查詢程式類的定義

我們將實現乙個簡單的文字查詢程式。功能很簡單,但是實現的思路值得學習

我們的程式允許使用者在乙個給定檔案中查詢單詞。查詢結果是單詞在檔案**現的次數及其所在行的列表。如果乙個單詞在一行**現多次, 此行只列出一次。行會按照公升序輸出

例如, 在某段文字中尋找單詞element。輸出結果的前幾行應該是這樣的:

element occurs 112 times

(line 36

) a set element contains only a key;

(line 158

)operator creates a new element

(line 160

) regardless of whether the element

(line 168

) when we fetch an element from a map, we

(line 214

) if the element is not found, find returns

開始乙個程式的設計的一種好方法是列出程式的操作。從需求入手, 我們的文字查詢程式需要完成如下任務:

利用標準庫設施, 我們可以很漂亮地實現這些要求:

我們將從定義乙個儲存輸入檔案的類textquery開始, 它包含乙個vector和乙個mapvector用來儲存輸入檔案的文字,map用來關聯每個單詞和它出現的行號的set

這個類將會有乙個用來讀取給定輸入檔案的建構函式和乙個執行查詢的操作。查詢操作要完成的任務非常簡單: 查詢map成員, 檢查給定單詞是否出現。設計這個函式的難點是確定應該返回什麼內容。一且找到了乙個單詞, 我們需要知道它出現了多少次、它出現的行號以及每行的文字。返回所有這些內容的最簡單的方法是定義另乙個類, 可以命名為queryresult, 來儲存查詢結果。這個類會有乙個print函式, 完成結果列印工作

我們的queryresult類要表達查詢的結果。這些結果包括與給定單詞關聯的行號的set和這些行對應的文字。這些資料都儲存在textquery型別的物件中。由於queryresult所需要的資料都儲存在乙個textquery物件中, 我們就必須確定如何訪問它們

當我們設計乙個類時, 在真正實現成員之前先編寫程式使用這個類, 是一種非常有用的方法。通過這種方法, 可以看到類是否具有我們所需要的操作

例如, 下面的程式使用了textqueryqueryresult類。這個函式接受乙個指向要處理的檔案的ifstream,並與使用者互動,列印給定單詞的查詢結果

void

runqueries

(ifstream &infile)

}

我們以textquery類的定義開始。使用者建立此類的物件時會提供乙個istream,用來讀取輸入檔案。這個類還提供乙個query操作, 接受乙個string, 返回乙個queryresult表示string出現的那些行

設計類的資料成員時, 需要考慮與queryresult物件共享資料的需求。queryresult類需要共享儲存輸入檔案的vector和儲存單詞關聯的行號的set。因此,這個類應該有兩個資料成員: 乙個指向動態分配的vector(儲存輸入檔案)的shared_ptr和乙個stringshared_ptrmap

為了使**更易讀, 我們還會定義乙個型別成員來引用行號, 即stringvector中的下標:

class

queryresult

;//為了定義函式query的返回型別, 這個定義是必需的

class

textquery

與往常一樣,對於可能置於標頭檔案中的**, 在使用標準庫名字時要加上std::

// 讀取輸入檔案並建立單詞到行號的對映

textquery::

textquery

(ifstream &is)

:file

(new vector)}

}

其實儲存行號用vector更好:雖然vector不會維護關鍵字的序,但是我們是逐行讀取輸入文字的,因此每個單詞出現的行號自然是按公升序加入容器的。並且在加入新的行號時只要和最後乙個行號比較一下就可以保證關鍵字不重複了。用這樣的方法插入 n

nn 個關鍵字的時間複雜度為 o(n

)o(n)

o(n)

,而使用set則需要 o(n

logn

)o(nlogn)

o(nlog

n)

queryresult類有三個資料成員:

class

queryresult

private

: std::string sought;

// 查詢單詞

std::shared_ptr> lines;

// 出現的行號

std::shared_ptr> file;

// 輸入檔案

query函式接受乙個string引數, 即查詢單詞,query用它來在map中定位對應的行號set。如果找到了這個string,query函式構造乙個queryresult, 儲存給定stringtextqueryfile成員以及從wm中提取的set

如果給定string未找到,我們定義了乙個區域性static物件, 它是乙個指向空的行號setshared_ptr。當未找到給定單詞時, 我們返回此物件的乙個拷貝:

queryresult

textquery::

query

(const string &sought)

const

ostream &

print

(ostream & os,

const queryresult &qr)

注意此函式能正確處理未找到單詞的情況。在此情況下,set為空。第一條輸出語句會注意到單詞出現了0次。由於*res.lines為空,for迴圈一次也不會執行

C 標準庫和C 標準模版庫

c 標準庫很大,在現在的情況下,c 標準庫確實越來越好,因為大的庫會包含大量的功能.標準庫中的功能越多,開發自己的應用程式時能借助的功能就越多,c 庫並非提供一切 很明顯的是沒有提供開發和圖形使用者介面的支援 但確實提供了很多.標準c 庫中主要有以下主要元件 標準c庫.i 0流技術.string.容...

C 標準模板庫使用

資料結構 描述 實現標頭檔案 向量 vector 連續儲存的元素 列表 list 由節點組成的雙向鍊錶,每個結點包含著乙個元素 雙佇列 deque 連續儲存的指向不同元素的指標所組成的陣列 集合 set 由節點組成的紅黑樹,每個節點都包含著乙個元素,節點之間以某種作用於元素對的謂詞排列,沒有兩個不同...

c標準IO庫使用

雖說大部分場合能用c的都可以用c 代替,但是對於開發庫,還是用c效率高。下面介紹c標準io庫 檔案操作標準i o庫函式 fopen fread fwrite fclose fflush fseek fgetc getc getchar fputc putc putchar fgets gets pr...