天天看點

C++ Primer 筆記十二 初識 vector

初識 vector

标準庫類型

vector

表示類型相同的對象的集合,因之可以容納其他對象,也被稱作容器(container)。引用不是對象,是以不存在引用的 vector 。

同 string 一樣,vector 也是對數組的某種抽象。

初始化

vector 是C++ 的一個類模闆而非類型,編譯器根據模闆建立類或者函數的過程稱為執行個體化,是以由 vector 生成的類型必須包含 vector 中元素的類型:

vector<int> ivec;				// 包含元素類型為int 
vector<vector<string>> file;	// 包含元素類型為 vector<string>
           

vector 對象常用的初始化方法:

vector<T> v1;					// vector 的元素類型為 T,元素執行預設初始化
								// 這是最常見的方式
vector<T> v2(v1);				// v2 中包含 v1 中所有元素的副本,
								// v2 和 v1 的元素類型必須相同
vector<T> v3 = v2;				// 等價與 vector<T> v3(v2)
vector<T> v4(n, val);			// v4 包含 n 個元素,每個元素的值為 val
vector<T> v5(n);				// v5 包含了 n 個執行了 值初始化 的元素
vector<T> v6{a, b, c, d};		// v6 包含了初始值個數的元素,這裡是 4,
								// 每個元素的的值被賦予相應的初始值
vector<T> v7 = {a, b, c, d};	// 等價于 vector<T> v7{a, b, c, d}
           

值初始化發生在隻提供 vector 對象容納的元素數量而略去初始值的時候,庫會根據元素類型來決定賦給元素的初值,如果 vector 中元素是内置類型,則元素初始值自動設為 0 ;如果是類類型,則由類預設初始化。

值初始化的兩個特殊限制:1. 對于要求明确提供初始值的類,必須提供初始的元素值,否則無法完成初始化工作;2. 隻提供了元素數量而沒有設定初始值,隻能使用直接初始化。

// 下面操作将引發錯誤
// error: conversion from ‘int’ to non-scalar type 
// ‘std::vector<int>’ requested
vector<int> v1 = 10;
           

vector 對象的操作

函數 效果
v.empty() v 為空的時候傳回真;否則為假
v.size() 傳回 v 中元素的個數
v.push_back(t) 在 v 的尾端添加一個值為 t 的元素
v[n] 傳回 v 中第 n 個位置上元素的引用
v1 = v2 用 v2 中元素的拷貝替換 v1 中的元素
v1 = {a, b, c} 用清單中的元素的拷貝替換 v1 中的元素
v1 == v2 v1 和 v2 相等當且僅當它們的元素數量相同且對應位置的元素值都相同
v1 != v2 同上
<, <=, >, >= 以字典順序進行比較

最常見的情況是,建立了一個空的 vector,然後使用成員函數

push_back()

向 vector 的尾部添加元素。

// 建立一個 vector 對象,包含 100 個類型為 int 的元素
// 元素的值從 1 ~ 100
vector<int> ivec;
for (int i = 0; i != 100; ++i) {
	ivec.push_buck(i);
}
           

可以通過下标通路 vector 中的元素:

// 對于上面的 ivec
cout << ivec[4] << endl;	// 輸出 5
           

類似 string,vector 的下标起始于 0,類型為 size_type,由 vector 定義,同 vector 對象的聲明一樣,使用 size_type 必須指定它的類型:

vector<int>::size_type i;	// OK

// 下面操作将引發錯誤
// error: ‘template<class _Tp, class _Alloc> class std::vector’ 
// used without template parameters
vector::size_type i2;	
           

下标的合法範圍在 0 到 size() - 1 之間,size() 函數傳回 vector 對象中元素的個數,類型為 size_type,不能通過下标形式添加元素:

// 編譯器不負責檢測下标的合法性
// 編譯通過,但在運作是引發錯誤
// 緩沖區溢出
vector<int> ivec;
ivec[0] = 4;	// error
           

兩個練習:

練習 3.16: 從 cin 讀入一組詞,并把它們存入一個 vector 對象,然後設法把所有詞都改寫為大寫形式。輸出改變後的結果,每個詞占一行。

// toup.cc
// P94 exercise 3.17

#include <iostream>
#include <vector>

using namespace std;

int main() {
	vector<string> sver;
	string temp;
	
	// use 'Ctrl-D' to send an EOF character
	while (cin >> temp) {
		if (temp == "\n")
			break;
		sver.push_back(temp);
	}
	
	for (auto &str : sver) {	// string &str
		for (auto &c : str) {	// char &c
			c = toupper(c);
		}
	}

	for (int i = 0; i != sver.size(); ++i) {
		cout << sver[i] << endl;
	}

	return 0;
}
           
$ ./toup.out 
when you are old and grey and full of sleep
WHEN
YOU
ARE
OLD
AND
GREY
AND
FULL
OF
SLEEP
           

練習 3. 20: 讀入一組整數,并把它們存入一個 vector 對象,将每對相鄰整數的和輸出。改寫程式,要求輸出第一個和最後一個元素的和,接着輸出第二個和倒數第二個元素的和,以此類推。

// add.cc
// P94 exercise 3.20
#include <iostream>
#include <vector>

// 通過類型别名避免多次聲明複雜的類型
using type = std::vector<int>::size_type;

int main(){
	std::vector<int> ivec;
	int temp;
	
	while(std::cin >> temp) {
		ivec.push_back(temp);
	}	
	
	type size = ivec.size();
	std::cout << "Size of ivec : " << size << std::endl << std::endl;

	// 列印相鄰元素的和
	for(type i = 0; i != size - 1; ++i) {
		std::cout << "ivec[" << i << "] + ivec["
			<< i + 1 << "] = " 
			<< ivec[i] + ivec[i+1]
			<< std::endl;
	}
	std::cout << std::endl;
	
	// 列印首尾對稱位置的和
	// decltype() 傳回變量的類型
	// 這裡 i 的類型是 vector<int>::size_type
	for(decltype(size) i = 0; i != size / 2 + 1; ++i) {
		std::cout << "ivec[" << i << "] + ivec["
			<< size - i - 1 << "] = "
			<< ivec[i] + ivec[size - i - 1]
			<< std::endl;
	}

	return 0;
}
           
$ ./add.out 
11 22 33 44 55 66 77 88 99
E
Size of ivec : 9

ivec[0] + ivec[1] = 33
ivec[1] + ivec[2] = 55
ivec[2] + ivec[3] = 77
ivec[3] + ivec[4] = 99
ivec[4] + ivec[5] = 121
ivec[5] + ivec[6] = 143
ivec[6] + ivec[7] = 165
ivec[7] + ivec[8] = 187

ivec[0] + ivec[8] = 110
ivec[1] + ivec[7] = 110
ivec[2] + ivec[6] = 110
ivec[3] + ivec[5] = 110
ivec[4] + ivec[4] = 110
           

好好學習天天向上~~╭(●`∀´●)╯ ヾ(*´▽‘*)ノ ~~

繼續閱讀