C++中的vector容器對象進修筆記。本站提示廣大學習愛好者:(C++中的vector容器對象進修筆記)文章只能為提供參考,不一定能成為您想要的結果。以下是C++中的vector容器對象進修筆記正文
C++中數組很坑,有無相似Python中list的數據類型呢?相似的就是vector! vector 是統一品種型的對象的聚集 ,每一個對象都有一個對應的整數索引值。和 string 對象一樣,尺度庫將擔任治理與存儲元素相干的內存。 我們把 vector 稱為容器,是由於它可以包括其他對象 。 一個容器中的一切對象都必需是統一品種型的 。
vector對象的界說和初始化
異樣的,應用前,導入頭文件#include <vector> 可使用using聲明:using std::vector;
vector 是一個類模板(class template)。應用模板可以編寫一個類界說或函數界說,而用於多個分歧的數據類型。是以,我們可以界說保留 string 對象的 vector,或保留 int 值的 vector,又或是保留自界說的類類型對象(如 Sales_items 對象)的 vector。
聲明從類模板發生的某品種型的對象,須要供給附加信息,信息的品種取決於模板。 以 vector 為例,必需解釋 vector 保留何種對象的類型,經由過程將類型放在類型放在類模板稱號前面的尖括號中來指定類型:
vector<T> v1;
保留類型為 T 對象。默許結構函數 v1 為空。
vector<T> v2(v1);
v2 是 v1 的一個正本。
vector<T> v3(n, i);
v3 包括 n 個值為 i 的元素。
vector<T> v4(n);
v4 含有值初始化的元素的 n 個正本。
【留意:1、若要創立非空的 vector 對象,必需給出初始化元素的值;2、當把一個 vector 對象復制到另外一個 vector 對象時,新復制的 vector 中每個元素都初始化為原 vectors 中響應元素的正本。但這兩個 vector 對象必需保留統一種元素類型;3、可以用元素個數和元素值對 vector 對象停止初始化。結構函數用元素個數來決議 vector 對象保留元素的
個數,元素值指定每一個元素的初始值】
vector對象靜態增加 :
vector 對象(和其他尺度庫容器對象)的主要屬性就在於 可以在運轉時高效地添加元素。
【留意:由於
vector 增加的效力高
,在元素值已知的情形下,最好是靜態地添加元素。】
值初始化:
假如沒有指定元素的初始化式,那末尺度庫將自行供給一個元素初始值停止,詳細值為什麼,取決於存儲在vector 中元素的數據類型。
假如為int型數據,那末尺度庫將用 0 值創立元素初始化式;
假如 vector 保留的是含有結構函數的類類型(如 string)的元素,尺度庫將用該類型的默許結構函數創立元素初始化式;
元素類型能夠是沒有界說任何結構函數的類類型。這類情形下,尺度庫仍發生一個帶初始值的對象,這個對象的每一個成員停止了值初始化。
#include <iostream> #include <string> #include <vector> int main() { std::vector<int> a; std::vector<int> b(a); std::vector<int> c(10, 23); std::vector<std::string> svec(10, "null"); std::vector<std::string> svec2(10, "hi!"); std::vector<std::string> svec3(10); return 0; }
留意,沒有=號!
vector對象操作辦法
和string相似!
.v.empty()
Returns true if v is empty; otherwise returns false假如 v 為空,則前往 true,不然前往 false。
.v.size()
Returns number of elements in v前往 v 中元素的個數。
【留意:1、前往響應 vector 類界說的size_type 的值,和string相似。2、應用 size_type 類型時,必需指出該類型是在哪裡界說的。vector 類型老是包含老是
包含 vector 的元素類型 vector<int>::size_type
】
v.push_back(t) Adds element with value t to end of v在 v 的末尾增長一個值為 t 的元素。以下為例子: #include <iostream> #include <string> #include <cctype> #include <vector> int main() { // read words from the standard input and store them as elements in a vector std::string word; std::vector<std::string> text; // empty vector while (std::cin >> word) { text.push_back(word); // append word to text for(std::vector<int>::size_type ix =0; ix != text.size(); ++ix) std::cout<<"Now text["<<ix<< "]is: "<<text[ix]<<std::endl; } return 0; }
成果為:
Hello Now text[0]is: Hello world! Now text[0]is: Hello Now text[1]is: world!
留意:
1、弗成以直接輸入vector對象! 和list差異太年夜了。。。
2、下標操作可以轉變已有元素:例如上例,可以在最初加上:text[0] = "elements";
3、固然和list一樣,確定不克不及text[100] = "elements";在Python中如許操作list報答下標越界, C++中編譯不會報錯,運轉主動加入!【 數組操作時這個會坑逝世你,不會報錯,不會加入!天經地義,緩沖區溢出了,黑客們太愛好了! 】
4、因為靜態增加, 不克不及先測試長度 ,而是輪回中靜態測試!不然會湧現莫明其妙的BUG!有人會擔憂效力?別擔憂!價值很小【內聯函數】。
v[n]
Returns element at position n in v前往 v 中地位為 n 的元素。
(1)v1 = v2[/code]
WordStrs elements in v1 by a copy of elements in v2把 v1 的元素調換為 v2 中元素的正本。
(2)v1 == v2[/code]
Returns true if v1 and v2 are equal假如 v1 與 v2 相等,則前往 true。
(3)!=, <, <=,>, and >=
Have their normal meanings堅持這些操作符慣有的寄義。
一個簡略的例子
讀入一段文本到 vector 對象,每一個單詞存儲為 vector 中的一個元素。把vector 對象中每一個單詞轉化為年夜寫字母。輸入 vector 對象直達化後的元素,每八個單詞為一行輸入。
假定文本為:in the vector. transform each word into uppercase letters. Print the transformed elements from the vector, printing eight words to a line.
#include <iostream> #include <string> #include <vector> std::string deal_word(std::string word) { std::string WORD; // 創立空字符串 for(std::string::size_type ix =0; ix != word.size(); ++ix) { if (not ispunct(word[ix])) { WORD += toupper(word[ix]); //銜接非標點字符到字符串 } } return WORD; } int main() { std::string word; // 緩存輸出的單詞 std::vector<std::string> text; // empty vector std::cout<<"Please input the text:"<<std::endl; //提醒輸出 while (std::cin >> word and word != "INPUTOVER") // INPUTOVER 用於標示輸出停止,也能夠ctrl + z停滯輸出 { word = deal_word(word); // 單詞處置 text.push_back(word); // append word to text } for(std::vector<int>::size_type ix =0, j = 0; ix != text.size(); ++ix, ++j) { if (j==8) // 8個單詞一行 { std::cout<<std::endl; //換行 j = 0; //從新計數 } std::cout<<text[ix]<<" "; //加空格! } return 0; }
成果為:
Please input the text: in the vector. transform each word into uppercase letters. Print the transformed elements from the vector, printing eight words to a line. INPUTOVER IN THE VECTOR TRANSFORM EACH WORD INTO UPPERCASE LETTERS PRINT THE TRANSFORMED ELEMENTS FROM THE VECTOR PRINTING EIGHT WORDS TO A LINE
vector.resize 與 vector.reserve
reserve是容器預留空間,但其實不真正創立元素對象,在創立對象之前,不克不及援用容器內的元素,是以當參加新的元素時,須要用push_back()/insert()函數。
resize是轉變容器的年夜小,而且創立對象,是以,挪用這個函數以後,便可以援用容器內的對象了,是以當參加新的元素時,用operator[]操作符,或許用迭代器來援用元素對象。
再者,兩個函數的情勢是有差別的,reserve函數以後一個參數,即須要預留的容器的空間;resize函數可以有兩個參數,第一個參數是容器新的年夜小,第二個參數是要參加容器中的新元素,假如這個參數被省略,那末就挪用元素對象的默許結構函數。上面是這兩個函數應用例子:
vector<int> myVec; myVec.reserve( 100 ); // 新元素還沒有結構, // 此時不克不及用[]拜訪元素 for (int i = 0; i < 100; i++ ) ...{ myVec.push_back( i ); //新元素這時候才結構 } myVec.resize( 102 ); // 用元素的默許結構函數結構了兩個新的元素 myVec[100] = 1; //直接操作新元素 myVec[101] = 2;
首次接觸這兩個接口或許會混雜,其實接口的定名就是對功效的絕佳描寫,resize就是從新分派年夜小,reserve就是預留必定的空間。這兩個接口即存在差異,也有配合點。上面就它們的細節停止剖析。
為完成resize的語義,resize接口做了兩個包管:
一是包管區間[0, new_size)規模內數據有用,假如下標index在此區間內,vector[indext]是正當的。
二是包管區間[0, new_size)規模之外數據有效,假如下標index在區間外,vector[indext]長短法的。
reserve只是包管vector的空間年夜小(capacity)起碼到達它的參數所指定的年夜小n。在區間[0, n)規模內,假如下標是index,vector[index]這類拜訪有能夠是正當的,也有能夠長短法的,視詳細情形而定。
resize和reserve接口的配合點是它們都包管了vector的空間年夜小(capacity)起碼到達它的參數所指定的年夜小。
因兩接口的源代碼相當精簡,以致於可以在這裡貼上它們:
void resize(size_type new_size) { resize(new_size, T()); } void resize(size_type new_size, const T& x) { if (new_size < size()) erase(begin() + new_size, end()); // erase區間規模之外的數據,確保區間之外的數據有效 else insert(end(), new_size - size(), x); // 彌補區間規模內空白的數據,確保區間內的數據有用 }