• 沒有找到結果。

標準樣板函式庫

N/A
N/A
Protected

Academic year: 2021

Share "標準樣板函式庫"

Copied!
41
0
0

加載中.... (立即查看全文)

全文

(1)

講師:洪安

1

標準樣板函式庫

(Standard Template Library)

(2)

大綱

標準樣板函式庫 (STL)

抽象指標 (Iterator)

容器 (Container)

演算法 (Algorithm)

(3)

標準樣板函式庫 (STL)

STL (Standard Template Library)

提供多種類別樣板以供使用

由以下三大部分所組成

Iterator (抽象指標)

Container (容器):

vector, list, stack, queue, map,…

Algorithm (演算法):

find, sort, count,…

3

(4)

大綱

標準樣板函式庫 (STL)

抽象指標 (Iterator)

容器 (Container)

演算法 (Algorithm)

(5)

抽象指標(Iterator)

Iterator 是一種可以讓使用者逐一存取 container 中元素的工具

所有 STL 的 container C 都有(甚至自己寫的 class )

使用者均可利用 C::iterator it; 的方式來宣告 iterator ,以取得容器內元素的位址

容器均有提供 begin( ) , end( ) 成員函數,讓使用 者取得容器的第一個元素的位址與最後一個元素後 一個的位址

5

(6)

抽象指標(Iterator)

範例:

#include<iostream>

#include<vector>

using namespace std;

int main() {

int a[7] = { 8, 1, 3, 2, 5, 1, 4};

vector<int> v(a,a+7);

vector<int>::iterator it ;

for ( it = v.begin( ); it != v.end( ) ; it++) cout << *it <<" ";

cout << endl;

return 0;

}

(7)

大綱

標準樣板函式庫 (STL)

抽象指標 (Iterator)

容器 (Container)

演算法 (Algorithm)

7

(8)

容器(Containers)

Vector

動態陣列,此陣列可任意增長其大小,並提供隨機存

List

雙向linked list,支援循序雙向存取(無法隨機存取)

Map

支援查表功能之資料結構,資料均以key/value方式 存入

其他… (stack, queue, set…)

(9)

向量 vector

vector其特性如同 陣 列 一 樣 , 但 又 比 內 建 的 陣 列 多 了 許 多 好 用 的 功 能

vector 可 以 動 態 成 長 , 可 以 將 一 個 vector 指 定 給 另一個vector

vector 知 道 自 己 內含元素的個數

9

常用函式

[n] 取得第索引值n之資料

size 計算長度

front 取得開頭元素

back 取得結尾元素

pop_back 移除結尾資料

push_back 新增資料於結尾

begin 取得開頭元素之抽象指標

end 取得結尾元素之抽象指標

insert 插入資料

erase 刪除資料

(10)

vector::vector

範例:

#include <iostream>

#include <vector>

using namespace std;

int main () {

int i;

int myints[] = {16,2,77,29};

vector<int> v1 (myints, myints + 4);

vector<int> v2;

v2 = v1;

for (i=0; i < v2.size(); i++) cout << " " << v2[i];

cout << endl;

return 0;

}

(11)

vector::pop_back, push_back

範例:

11

#include <iostream>

#include <vector>

using namespace std;

int main () {

vector<int> v;

int sum=0;

v.push_back (100);

v.push_back (200);

v.push_back (300);

while (!v.empty()) {

sum+=v.back();

v.pop_back();

}

cout << "sum = " << sum << endl;

return 0;

}

(12)

vector::begin, end

範例: #include <iostream>

#include <vector>

using namespace std;

int main () {

vector<int> v;

vector<int>::iterator it;

for (int i=1; i<=5; i++) v.push_back(i);

for ( it=v.begin() ; it < v.end(); it++ ) cout << " " << *it;

cout << endl;

return 0;

}

(13)

vector::insert

範例:

13

// inserting into a vector

#include <iostream>

#include <vector>

using namespace std;

int main () {

int i;

vector<int> v;

int a[] = { 10,20,30 };

v.insert (v.begin(), a, a+3); //插入一段資料於開頭

v.insert (v.begin()+1,15); //插入一筆資料於第二個位子 v.insert (v.end(),100); //插入一筆資料於最後

for (i=0; i<v.size(); i++) cout << " " << v[i];

cout << endl;

return 0;

}

10 20 30

10 15 20 30

10 15 20 30 100

(14)

vector::erase

範例: #include <iostream>

#include <vector>

using namespace std;

int main () {

int i;

vector<int> v;

for (i=1; i<=10; i++) v.push_back(i);

v.erase (v.begin()+5); //指定一筆資料刪除

v.erase (v.begin(),v.begin()+3); //刪除一段資料 for (i=0; i<v.size(); i++)

cout << " " << v[i];

cout << endl;

return 0;

begin begin+1 begin+2 begin+3 begin+4 begin+5 begin+6 begin+7 begin+8 begin+9

1 2 3 4 5 6 7 8 9 10

(15)

串列 list

list其特性主要為實作串列資料結構

常用函式

size 計算長度

front 取得開頭元素

back 取得結尾元素

begin 取得開頭元素之抽象指標

end 取得結尾元素之抽象指標

pop_back, (pop_front) 移除結尾(開頭)資料 push_back,

(push_front)

新增資料於結尾(開頭)

insert 插入資料

erase 刪除資料

remove 指定一個資料內容,並刪除

reverse 資料反置

merge 合併資料

15

(16)

list::remove

範例: #include <iostream>

#include <list>

using namespace std;

int main () {

int a[]= {17,89,7,14};

list<int> L (a,a+4);

list<int>::iterator it;

L.remove(89);

for (it=L.begin(); it!=L.end(); ++it) cout << " " << *it;

cout << endl;

return 0;

(17)

list::reverse

範例: #include <iostream>

#include <list>

using namespace std;

int main () {

list<int> L;

list<int>::iterator it;

for (int i=1; i<10; i++) L.push_back(i);

for (it=L.begin(); it!=L.end(); ++it) cout << " " << *it;

cout << endl;

L.reverse(); //反轉串列

for (it=L.begin(); it!=L.end(); ++it) cout << " " << *it;

cout << endl;

return 0;

} 17

(18)

list::merge

範例: #include <iostream>

#include <list>

using namespace std;

int main () {

list<double> L1, L2;

list<double>::iterator it;

L1.push_back (3.1);

L1.push_back (2.2);

L1.push_back (2.9);

L2.push_back (3.7);

L2.push_back (7.1);

L2.push_back (1.4);

L1.merge(L2);

L2.push_back (2.1);

L1.merge(L2);

for (it=L1.begin(); it!=L1.end(); ++it) cout << *it << endl;

請寫一段程式碼看看L2此時的內容

(19)

映射表 map

1 9

map是一種關聯容器,支援查表功能之資料結構,資 料均以key/value方式存入

常用函式

[n] 取得key值為n之value

size 計算長度

find 尋找資料

erase 刪除資料

insert 插入資料

count 判斷資料是否存在

lower_bound, (upper_bound)

取得接近下限(上限)之 資料

(20)

map::map

範例:

#include <iostream>

#include <map>

#include <string>

using namespace std;

int main () {

map<char,string> m;

map<char,string>::iterator it;

m['a']="Andy Lee";

m['b']="Joe Wang";

m['c']="Mary Lin";

for (it=m.begin();it!=m.end();it++) {

cout << "m['" << (*it).first << "'] is " << (*it).second << endl;

}

cout << "m now contains " << m.size() << " elements." << endl;

(21)

map::find, erase

範例:

21

// erasing from map

#include <iostream>

#include <map>

using namespace std;

int main () {

map<char,int> m;

map<char,int>::iterator it;

// insert some values:

m['a']=10;

m['b']=20;

m['c']=30;

m['d']=40;

m['e']=50;

m['f']=60;

it=m.find('b');

m.erase (it); // 刪除it位置之資料 m.erase ('c'); // 刪除key為'c'之資料 it=m.find ('e');

m.erase ( it, m.end() ); // 刪除一段資料 for ( it=m.begin() ; it != m.end(); it++ )

cout << (*it).first << " => " << (*it).second << endl;

return 0;

}

(22)

map::insert

範例: #include <iostream>

#include <iomanip>

#include <string>

#include <map>

using namespace std;

int main() {

string s[][2] = {

{"black", "#ffffff"}, {"white", "#000000"}, {"blue", "#0000ff"}, {"red", "#ff0000"}, {"green", "#00ff00"}, {"", ""}

};

map<string, string> m;

map<string, string>::iterator it;

for (int i = 0; !s[i][0].empty(); ++i)

m.insert(map<string,string>::value_type(s[i][0], s[i][1]));

for (it = m.begin(); it != m.end(); ++it) {

cout << (*it).first << " => " << (*it).second << endl;

}

if ((it = m.find("blue")) != m.end()) {

cout << "'blue' Find! It's value is " << (*it).second << endl;

}

black

#ffffff

(23)

map::count

範例:

23

#include <iostream>

#include <map>

using namespace std;

int main () {

map<char,int> m;

char c;

m ['a']=101;

m ['c']=202;

m ['f']=303;

for (c='a'; c<='h'; c++) {

cout << c;

if (m.count(c)>0) cout << " yes.\n";

else

cout << " no.\n";

}

return 0;

}

(24)

map::lower_bound, upper_bound

範例: // map::lower_bound/upper_bound

#include <iostream>

#include <map>

using namespace std;

int main () {

map<char,int> m;

map<char,int>::iterator it,itlow,itup;

m['a']=20;

m['c']=40;

m['d']=60;

m['g']=80;

m['i']=100;

itlow=m.lower_bound ('b'); // 設定下限 itup=m.upper_bound ('d'); // 設定上限

m.erase(itlow,itup); // 刪除下限到上限所有資料 // print content:

for ( it=m.begin() ; it != m.end(); it++ )

cout << (*it).first << " => " << (*it).second << endl;

upper_bound():

回傳一個 iterator pointing 指到第一 個container中key 比input大的元素,

相等時不回傳

lower_bound():

回傳一個 iterator pointing 指到第一 個container中key 不比input小的元素,

相等時會回傳

(25)

大綱

標準樣板函式庫 (STL)

抽象指標 (Iterator)

容器 (Container)

演算法 (Algorithm)

25

(26)

演算法(Algorithm)

STL中的演算法

在STL中除了提供容器(類別樣板), 尚提供演算法(函式 樣板)以供操作之資料

#include <algorithm>

常用演算法

find

count

search

merge

sort

for_each

transform

(27)

find

find(first, last, val)

[first]: iterator

[last]: iterator

[val]: target value type

[回傳值]: iterator

針對某個container做搜尋,區間由first及last這兩 個iterator指定,目標值為val,找到後回傳其所在 元素指標(也是以iterator表示)

函數模板原型

27

template<class InIt, class T>

InIt find(InIt first, InIt last, const T& val);

(28)

find

範例 #include<iostream>

#include<list>

#include<algorithm>

using namespace std;

int main( ) {

list<int> L;

list<int>::iterator it;

L.push_back(10) ; L.push_back(20);

L.push_back(30);

it = find(L.begin( ), L.end( ), 30);

if ( it == L.end( ))

cout << "data not found\n";

else

cout << *it << endl;

return 0;

}

#include<iostream>

#include<algorithm>

using namespace std;

int main( ) {

int l[7] = { 1, 3, 2, 5, 1, 2, 1 };

int *it ;

it = find(&l[0], &l[7], 5);

if ( it == l+7)

cout << "data not found\n" ; else

cout << *it << endl;

return 0;

}

(29)

count

count(first, last, val)

[first]: iterator

[last]: iterator

[val]: target value type

[回傳值]: int

針對某個container做搜尋,區間由first及last這兩 個iterator指定,目標值為val,回傳container中 元素值為val的個數

函數模板原型

29

template<class InIt, class T>

int count(InIt first, InIt last, const T& val);

(30)

count

範例

#include<iostream>

#include<vector>

#include<algorithm>

using namespace std;

int main() {

int a[7] = { 1, 3, 2, 4, 1, 2, 1};

vector<int> v(a,a+7);

int count_of_1;

count_of_1 = count(v.begin(), v.end(), 1);

cout << "count of 1 = " <<count_of_1<<endl;

return 0;

}

(31)

search

search(s_first, s_last, t_first, t_last)

[s_first][t_first]: iterator

[s_last][t_last]: iterator

[回傳值]: iterator

找尋某一資料序列是否出現在另一個容器中

函數模板原型

31

template<class FwdIt1, class FwdIt2>

FwdIt1 search(FwdIt1 first1, FwdIt1 last1, FwdIt2 first2, FwdIt2 last2);

(32)

search

範例:在STL的list容器中做搜尋

#include<iostream>

#include<list>

#include<vector>

#include<algorithm>

using namespace std;

int main( ) {

int a[7] = { 1, 3, 2, 5, 1, 2, 1};

vector<int> v(a,a+7) ; vector<int>::iterator it ; list<int> L ;

L.push_back(5) ; L.push_back(1); L.push_back(2) ; it = search(v.begin( ), v.end( ), L.begin( ), L.end( ));

if (it != v.end( )) //有找到

cout << *it << " " << *(it+1) << " " << *(it+2) << endl ;

(33)

merge

merge(s1_first, s1_last, s2_first, s2_last, t_first)

[s1_first][s2_first]: iterator

[s1_last][s2_last]: iterator

[t_first]: iterator

[回傳值]: iterator

合併s1與s2兩資料於t

函數模板原型

33

template<class InIt1, class InIt2, class OutIt>

OutIt merge(InIt1 first1, InIt1 last1, InIt2 first2, InIt2 last2, OutIt x);

(34)

merge

範例: #include<iostream>

#include<vector>

#include<algorithm>

using namespace std;

int main( ) {

int a[7] = { 3, 2, 5, 1, 2, 1, 8 } ; int b[4] = { 1, 7, 4, 9 } ;

vector<int> v1(a,a+7) ; vector<int> v2(b,b+4) ;

vector<int> v3(v1.size( ) + v2.size( )) ;

merge(v1.begin( ),v1.end( ),v2.begin( ),v2.end( ), v3.begin( ));

for (int i=0 ; i<v3.size( ) ; i++ ) cout << v3[i] << " " ;

cout << endl;

return 0;

}

這個結果是怎麼來的?

(35)

sort

sort(first, last)

sort(first, last, f)

[first]: iterator

[last]: iterator

[f]: 函式

[回傳值]: void

資料排序 (預設由小到大)

函數模板原型

35

template<class RanIt>

void sort(RanIt first, RanIt last);

template<class RanIt, class Pred>

void sort(RanIt first, RanIt last, Pred pr);

(36)

sort

範例:

#include<iostream>

#include<vector>

#include<algorithm>

using namespace std;

bool mygreater(int x, int y) {

return x>y;

}

int main() {

int a[7] = { 8, 1, 3, 2, 5, 1, 4};

vector<int> v(a,a+7);

vector<int>::iterator it ;

sort(v.begin( ), v.end( )) ; //由小排到大 for ( it = v.begin( ); it != v.end( ) ; it++)

cout << *it <<" ";

cout << endl;

sort(v.begin( ), v.end( ), mygreater) ; //mygreater 由大排到小 for ( it = v.begin( ); it != v.end( ) ; it++)

cout << *it <<" ";

cout << endl;

←改成函數樣板試試看

(37)

for_each

for_each(first, last, f)

[first]: iterator

[last]: iterator

[f]: 函式

[回傳值]: 函數物件指標

對container中從first 所指的元素起到last為止,其 間每一個元素做某個動作(由函數f指定)

函數模板原型

37

template<class InIt, class Fun>

Fun for_each(InIt first, InIt last, Fun f) ;

(38)

for_each

範例:

#include<iostream>

#include<list>

#include<algorithm>

using namespace std;

void print(int &x) {

cout << x << " ";

}

void add(int &x) {

x = x+5;

}

int main( ) {

list<int> L ;

L.push_back(10);

L.push_back(20) ; L.push_back(30) ;

for_each(L.begin( ), L.end( ), print) ; cout << endl;

for_each(L.begin( ), L.end( ), add) ; for_each(L.begin( ), L.end( ), print) ; cout << endl;

return 0;

(39)

transform

transform(first, last, output, f)

[first]: iterator

[last]: iterator

[output]: container

[f]: 函式

[回傳值]: 函數物件指標

同for_each,但會把結果放在output容器中

函數模板原型

39

template<class InIt, class OutIt, class Unop>

OutIt transform(InIt first, InIt last, OutIt x, Unop uop);

(40)

transform

範例:

#include<iostream>

#include<list>

#include<vector>

#include<algorithm>

using namespace std;

void print(int &x) {

cout << x << " ";

}

int add(int x) {

return x+5;

}

int main( ) {

list<int> L ;

vector<int> v(3) ; L.push_back(10);

L.push_back(20) ; L.push_back(30) ;

transform(L.begin( ), L.end( ), v.begin(), add) ; for_each(L.begin( ), L.end( ), print) ;

cout << endl;

for_each(v.begin( ), v.end( ), print) ; cout << endl;

(41)

STL參考網站

http://www.cplusplus.com/reference/stl/

41

參考文獻

相關文件

– at a premium (above its par value) when its coupon rate c is above the market interest rate r;. – at par (at its par value) when its coupon rate is equal to the market

– at a premium (above its par value) when its coupon rate c is above the market interest rate r;. – at par (at its par value) when its coupon rate is equal to the market

•Q :依據討論出的檢核標 準,評核這些組的內容.. •小組討論 (

•Last month I watched a dance class in 崇文 Elementary School and learned the new..

Forming expectations on texts and text interpretation and being higher-order generic and language skills to be fostered, and a way to differentiate the content for students 27

during daytime. The barn owl is endangered because people are moving to barns and also because mice eat chemicals and the owls eat the mice and they die. 57). Stage 2:

In this paper, we extended the entropy-like proximal algo- rithm proposed by Eggermont [12] for convex programming subject to nonnegative constraints and proposed a class of

Segment/Interval Tree in class. by