<b>15.2 stl理念</b>
<b></b>
c++标準庫為處理資料序列提供了一個專門的架構,稱為stl。stl是标準模闆庫(standard template library)的簡稱。stl是iso c++标準庫的部分,它提供了容器(例如vector、list和map)和通用算法(例如sort、f?ind和accumulate)。是以我們可以稱vector這類對象為stl或标準庫的一部分。标準庫的其他部分,例如ostream(第10章)和c風格的字元串處理函數(附錄c.10.3),并不屬于stl。為了更好地了解stl,我們首先考慮在處理資料時必須要解決的問題和對求解方案的理念。
計算過程包含兩個主要方面:計算和資料。有時我們隻關注計算方面,談論if語句、循環、函數和錯誤處理等。有時我們關注的是資料,談論數組、向量、字元串和檔案等。然而,要完成真正的工作我們需要同時考慮計算和資料。如果對大量資料不進行分析、可視化和查找“感興趣的部分”,則資料是無法了解的。相反,我們可以随心所欲地進行計算,但是隻有與實際資料關聯之後,才能避免枯燥乏味的無意義計算。而且,“計算部分”要優雅地與“資料部分”進行互動。
當談起資料時,我們會想到很多類型的資料:數十個形狀、數百個溫度值、數千個日志記錄、數百萬個點、數十億個網頁等,即我們在讨論資料的容器、資料流等。特别地,我們并不是要讨論如何為一個小對象(例如,一個複數、一個溫度讀數或一個圓形等)選擇最恰當的數值。對于這些類型,可以參看第9、11和19章。
考慮我們需要對“大量資料”進行的一些簡單操作:
按照字典序排序。
根據姓名在電話本中找到對應的電話号碼。
找出溫度的最高值。
找出所有大于8800的值。
找出第一個值為17的元素。
根據單元編号對遙測記錄進行排序。
根據時間戳對遙測記錄進行排序。
找出第一個值大于“petersen”的元素。
找出最大值。
找出兩個序列的第一個不同之處。
計算兩個序列中對位元素兩兩之積。
找出一個月中每天的最高氣溫。
在銷售記錄中找出最暢銷的10件商品。
統計“stroustrup”在網頁中出現的次數。
計算各個元素之和。
注意,我們在讨論上述資料處理任務時,并沒有提到資料如何存儲。很顯然,我們必須使用連結清單、向量、檔案和輸入流等來完成這些任務,但是我們不必了解這些資料存儲(或收集)的細節,即可讨論如何對它們進行處理。重要的是這些值或對象的類型(元素類型),我們如何通路這些值或對象,以及要對它們進行什麼操作。
這些任務非常常見,我們自然希望能編寫代碼簡單高效地完成這些任務。與之相對,我們需要考慮的問題是:
資料類型(“資料種類”)變化萬千。
資料集存儲方法多到讓人眼花缭亂。
我們想對資料集執行的任務也數量繁多。
為了盡可能降低這些問題的影響,我們希望編寫的代碼能夠處理各種資料類型,處理各種資料存儲方法,适用于各種處理任務。換句話說,我們想通過泛化代碼來适應各種變化。我們要避免對每一個問題都從頭開始尋找處理方法,那樣會浪費大量的時間。
為了編寫能夠達到上述目的的代碼,首先用更加抽象的方式來看待我們要對資料進行的處理工作:
收集資料并裝入容器。
例如vector、list和數組。
組織資料。
用于列印;
用于快速通路。
提取資料。
通過索引(例如,第42個元素);
通過值(例如,年齡字段是7的第一條記錄);
根據屬性(例如,所有溫度字段大于32小于100的記錄)。
修改容器。
增加資料;
減少資料;
排序(根據某種标準)。
進行簡單的數值運算(例如,将每一個元素乘以1.7)。
我們在完成上述任務時要避免陷入各種細節之中:各種容器間的差别、各種資料元素通路方法間的差别以及各種資料類型間的差别。如果我們能夠做到這一點,就等于向編寫簡單高效的通用代碼的目标邁出了一大步。
回顧前面幾章介紹的程式設計工具和技術,我們(已經)可以編寫功能相似但與資料類型無關的代碼:
使用int與使用double基本沒有差異。
使用vector<int>與使用vector<string>基本沒有差異。
使用double類型的數組與使用vector<double>基本沒有差異。
我們希望通過合理組織代碼,實作隻有當我們想要完成一些全新的任務時才需要編寫新的代碼。特别是,我們希望編寫一些完成基本任務的代碼,使得我們不必每次發現一種新的資料存儲方式或資料解釋方式時都重寫整個程式。
在vector中查找一個值與在數組中查找一個值差異不大。
查找string時不區分大小寫與區分大小寫的差異不大。
繪制實驗資料圖時使用準确值與使用四舍五入值的差異不大。
拷貝檔案與拷貝vector對象的差異不大。
根據上面的發現,我們希望編寫的代碼具有以下特點:
容易閱讀。
容易修改。
規範。
簡短。
快速。
為了簡化程式設計工作,我們會:
使用統一的方式通路資料。
與資料存儲方法無關;
與資料類型無關。
使用類型安全的方式通路資料。
便于周遊資料。
緊湊存儲資料。
快速
讀取資料;
删除資料。
對通用算法提供标準實作。
例如拷貝、查找、搜尋、排序、求和等。
stl提供了上述功能以及更多。我們不應僅僅将它看作一個強大的功能庫,更應看作一個兼顧靈活性與性能的函數庫設計的典範。stl由alex stepanov設計,提供了一個作用于資料結構之上的通用、正确和高效的算法架構。其設計理念滿足簡單性、通用性和數學上的優雅。
除了使用設計理念和原則清晰的架構來處理資料之外,另一種政策是讓程式員使用最基本的語言特性從頭開始編寫每個程式,并采用一些當時看起來不錯的思想。這種方式費時費力,而且得到的程式代碼往往非常糟糕,毫無章法可言,除作者之外的人很難了解,而且在其他場合能夠複用的可能性微乎其微。
在介紹完stl的設計初衷和理念之後,我們會給出stl的一些基本定義,最後通過例子展示如何在實際應用中運用這些基本理念:編寫更好的處理資料的代碼,而且讓編寫過程更簡單。