【stanford C++】容器III——Vector类
主要介紹如下5個容器類——Vector, Stack,Queue,Map和Set,各個都表示一重要的抽象數據類型。另外,各個類都是一些簡單類型的值的集合,所以稱它們為容器類。
?
暫且我們先不需要知道它們是如何實現的,我們先來學習一下如何使用它們。
?
為了能使用這些容器類,必須包含適合的接口,就像包含相應的庫一樣。如下:
#include "vector.h"
就是包含了Vector類的接口,包含該頭文件后,就可以在程序中使用Vector類了。
?
一、Vector類
Vector類類似于C++中數組,然后,C++中數組有如下的缺點:
- 數組在定義時指定其大小,后續不能改變。
- 盡管數組有固定的大小,但是程序員不能獲取該大小。結果就是,需要一個額外的變量來跟蹤數組中的元素數目。
- 傳統的數組不支持插入和刪除元素。
- C++中數組不能確保你選擇的數據一定存在于數組中,例如,當一個數組保存了25個元素,當要選擇索引為50的位置的元素時,C++將簡單的查看內存位置,若存在則就查看到。
Vector類通過抽象數據類型來重新實現數組概念來解決這些問題,
1.指定Vector的基本類型
如Vector<int>表示一個Vector,其元素是整型。
Vector<char>表示一個Vector,其元素是單個字符
Vecotr<string>表示一個Vector,其元素是字符串。
尖括號里的類型,就表示為指定容器類的基本類型(Base Type)。
?
這種類中包含指定的基本類型在面向對象社區中稱為參數化的類。在C++中,參數化的類另外稱為模板(templates)。這反映了C++編譯器把Vector<int>,Vector<char>,Vector<string>作為獨立的類來共享共同的結構。
?
2.聲明一個Vector對象
抽象數據類型背后的一個哲學原理是讓Client認為它們就是內置的原始類型,就像如下聲明一個整型變量一樣
int n;
聲明一個新的Vector變量寫為:
Vecotr<int> vec;
在C++中,該聲明的新變量vec,表示是一個整型的Vector。
?
3.Vector操作
1)add操作
當聲明一個Vector變量時,其為一個空的Vector,表示它不包含任何元素,由于空的Vector并沒有用,因此,首先我知道的是如何向Vector變量中加入元素。常用的方法是調用add方法,該方法是在Vector尾部加入一個新的元素。
例如,若vec是一個空的整型Vector,執行如下加入元素操作:
vec.add(10);
vec.add(20);
vec.add(40);
這樣,vec中就包含了10,20,40這3個元素?,F在vec看起來如下:
跟原始的數組類型不同,Vector類的大小不是固定的,這意味著我們在任何時候加入其它元素。例如,現在我們再加入一個元素:
vec.add(50);
此時,加入50到vec的尾部,如下:
?
2)insertAt方法
該方法允許在一個Vector類的中間位置加入一個元素,insertAt方法的第一個參數為索引號,其表示在該索引號位置前插入一個新元素,例如:
vec.insertAt(2, 30);
表示在位置2之前插入一個值30,執行該語句后,如下:
3)removeAt方法
該方法表示從Vector變量中刪除一個元素,例如:
vec.removeAt(0);
表示刪除位置0處的元素,執行該語句后,如下:
4)get方法和set方法
get方法和set方法用來選擇和修改各個單獨的元素,get方法通過一個索引號獲取該索引位置的值。例如,對于上面最近顯示的vec變量中的值。調用
vec.get(2)
將返回40。
相應地,可以使用set方法來改變已經存在的元素的值,例如,調用
vec.set(3, 70);
其改變索引位置3的值50為70,如下:
?
get、set、insertAt和removeAt方法都會檢查給其提供的索引值必須是有效的。例如,對于上面最近顯示的Vector,若調用vec.get(4),則會有調用錯誤,因為索引值4太大了,因為vector的索引值從0~3。
這種檢查索引值的操作是否有效的操作,稱之為邊界檢查。邊界檢查可以更容易的獲取到那些不容易注意的程序錯誤
?
4.選擇Vector中的元素
盡管get和set方法容易使用,但并不是每個人都調用這些方法。
C++的一個特性是其定義的類可以重載標準操作符的定義。這讓Vector類支持更多傳統的使用方括號來指定要訪問的索引的值的語法。
因此,選擇位置i處的元素,可以使用表達式vec[i],就像訪問傳統的數組一樣。
另外,可以通過賦值一個新的值給vec[i]來改變位置i處的值??梢酝ㄟ^如下:
vec[3] = 70;
來設置索引值3的處為70。
?
最常用的索引表達式之一就是for循環中的索引,其按序循環各個索引值。循環Vector中的索引位置的通常模式如下:
for(int i = 0; i < vec.size(); i++)
{loop body
} 在循環實體內,可以應用當前的元素vec[i]。
例如,如下的代碼把Vec變量中的內容,以方括號括起來,元素之間用逗號隔開來顯示
cout << "[";
for(int i = 0; i < vec.size(); i++)
{if(i > 0) cout << ",";cout << vec[i];
}
cout << "]" << endl; 執行該段代碼的輸出結果將如下:
[20,30,40,70]
?
5.傳遞Vector對象作為一個參數
對于上面的打印Vector變量中的元素值使用的非常頻繁,因此,可以把其定義為一個函數,后面若使用,直接調用該函數即可,那么在定義函數時,就涉及了Vector變量傳遞給函數參數的問題,一般Vector變量作為函數參數的定義如下:
void printVector(Vector<int> &vec)
{cout << "[";for(int i = 0; i < vec.size(); i++){if(i > 0) cout << ",";cout << vec[i];}cout << "]" << endl;
}
&表示此處參數通過引用來調用,
在C++中,引用調用比傳值調用更有效,因為傳值調用要求復制vector中的每個元素。
在printVector函數中,并沒需要進行復制,所以引用調用是一個更加有效的設計。
?
引用調用的一個更加重要的特性就是可以直接改變Vector變量中的內容,例如,使用如何函數刪除元素值為0的項。
void removeZeroElements(Vector<int> &vec){for(int i = vec.size() - 1; i >= 0; i--)if(vec[i] == 0)vec.removeAt(i);}
}
6.創建一個預先定義大小的Vector
到目前為止的例子,都是創建一個空Vector變量,然后一次加入一個元素到里面。然而,若提前知道要創建的vector變量的大小,則可以在聲明時指定元素個數。如下代碼:
const int N_HOLES = 18;
Vector<int> golfScores;
for(int i = 0; i < N_HOLES; i++)
{golfScores.add(0);
} 一個較好的方法是在聲明的時候包含一個大小的參數,如下:
Vector<int> golfScores(N_HOLES);
該聲明創建一個Vector<int>變量指定大小為N_HOLES個元素,各個元素初始化為0.
?
?
轉載于:https://www.cnblogs.com/snake-hand/p/3206532.html
總結
以上是生活随笔為你收集整理的【stanford C++】容器III——Vector类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 同余与模运算
- 下一篇: 一个较为详细的ETL系统实现方案