C/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)的元素,標准庫將用該類型的默認構造函數創建元素初始化式;
元素類型可能是未定義不論什么構造函數的類類型。這樣的情況下。標准庫仍產生一個帶初始值的對象,這個對象的每一個成員進行了值初始化。
/*
 * vector_test.cpp
 *
 *  Created on: 2014年6月24日
 *      Author: The_Third_Wave
 */
#include <iostream>
#include <string>
#include <vector>
using std::string; using std::vector; using std::cout; using std::endl;

void pr_int_vector(vector<int> vec)
{
    for(auto &v :  vec)
    {
    	cout<<v<<" ";
    }
    cout<<endl;
}

void pr_str_vector(vector<string> vec)
{
    for(auto &v :  vec)
    {
    	cout<<v<<" ";
    }
    cout<<endl;
}

int main()
{
	vector<int> a;
	vector<int> b(a);
	vector<int> c(10, 23);
	vector<string> s1(10, "null");
	vector<string> s2(10);
    vector<string> s3 = {10, "hi!"}; // 重點關注
    vector<string> s4 = {"10", "hi!"}; // 重點關注
    pr_int_vector(a);
    pr_int_vector(b);
    pr_int_vector(c);
    pr_str_vector(s1);
    pr_str_vector(s2);
    pr_str_vector(s3);
    pr_str_vector(s4);
    return 0;
}
注意,沒有=號!結果例如以下:
23 23 23 23 23 23 23 23 23 23 
null null null null null null null null null null 
          
hi! hi! hi! hi! hi! hi! hi! hi! hi! hi! 
10 hi! 

【更新於2014.06.25】能夠利用函數重載。僅僅有1個函數名(臨時和Python還是有區別的,為什么不能僅僅定義一個函數呢?自己主動識別參數。興許待求證)

void pr_vector(const vector<int> &vec)
{
	// 由於是輸出而不是改動。定義形參為常量引用,提高可靠性和效率!
    for(auto &v :  vec)
    {
    	cout<<v<<" ";
    }
    cout<<endl;
}

void pr_vector(const vector<string> &vec)
{
	// 由於是輸出而不是改動,定義形參為常量引用。提高可靠性和效率!
    for(auto &v :  vec)
    {
    	cout<<v<<" ";
    }
    cout<<endl;
}

至於為什么range for 語句里使用的還是引用(&),保持好習慣!

並且,這樣的情況真的去改動值,會報錯,由於是const & 類型,函數中不能改變實參!

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對象!

和Python區別太大了。。

2、下標操作能夠改變已有元素:比如上例。能夠在最后加上:text[0] = "elements";
3、當然和list一樣,肯定不能text[100] = "elements";在Python中這樣操作list會報下標越界, C++中編譯不會報錯。執行自己主動退出!【 數組操作時這個會坑死你。不會報錯,不會退出!

理所當然,緩沖區溢出了,黑客們太喜歡了。

4、由於動態增長。 不能先測試長度,而是循環中動態測試!否則會出現莫名其妙的BUG!

有人會操心效率?別操心!代價非常小【內聯函數【更新於2014.06.25:內聯函數,在函數返回類型前面用關鍵詞inline定義----目的是把函數內聯到主程序里面。相當於嵌入。作用就是省略了保存當前位置,調到函數位置執行再跳轉的過程。】】。

v[n] 

Returns element at position n in v返回 v 中位置為 n 的元素。

v1 = v2 

Replaces elements in v1 by a copy of elements in v2把 v1 的元素替換為 v2 中元素的副本。

v1 == v2 

Returns true if v1 and v2 are equal假設 v1 與 v2 相等,則返回 true。

!=, <, <=,>, 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.

【2014.06.24備注:使用c++11新特性的改寫樣例在C/C++中字符串String及字符操作方法http://blog.csdn.net/zhanh1218/article/details/33306481)一文中

#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 

本文由@The_Third_Wave(Blog地址:http://blog.csdn.net/zhanh1218)原創。由於還有部分內容沒有接觸,僅僅講了大概沒有原因。會不定期更新,有錯誤請指正。

假設你看到這篇博文時發現不完整。那是我為防止爬蟲先公布一半的原因,請看原作者Blog。

假設這篇博文對您有幫助,為了好的網絡環境,不建議轉載,建議收藏!假設您一定要轉載。請帶上后綴和本文地址。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM