返回

STL入门导论[原+译]

发布时间:2022-10-25 09:00:06 314

STL入门引导

STL主要有以下六个大的部分:

迭代器(iterators)

迭代器可以理解为一个模板指针;迭代器技术能够使程序反复的对STL容器的内容进行访问;

算法(alogrithms)

STL提供了很多的数据结构算法,这些算法在std命名空间中定义,通过#include来获得使用权。如常用的算法有:for_each()、find()、find_if()、count()、replace()、copy()、sort()、merge等

容器(containers)

常见的容器有:向量容器vector、双向链表容器list、双端队列容器deque、集合容器set、多重集合容器multiset、映射容器map、多重映射容器multimap

函数对象(function objects)

内存分配器(allocators)

适配器(adapter)

适配器是一种泛化的模板类型。STL提供的适配器主要分为迭代器适配器、函数对象适配器、容器适配器,分别用来进行迭代器、函数对象和容器的转换。

1.

用标准的std命名空间,using namespace std;

2.

1.在Debug模式下,忽略如下警告信息:#pragma warning(disable: 4786)

2.当定义如下容器时:

不要写成vector <list> veclis;而要vector > veclis;也即是在‘>’与‘>’之间,加一个空格;

3.     copy算法的巧用

对于如下程序的输出;

 

#include 

#include

#include

using namespace std;

#pragma warning(disable: 4786)

int main(int argc, char* argv[])

{

set <string> strset;

set <string>::iterator si;

strset.insert("cantaloupes");

strset.insert("apple");

strset.insert("orange");

strset.insert("banana");

strset.insert("grapes");

strset.insert("grapes");

// This one overwrites the previous occurrence

for (si=strset.begin(); si!=strset.end(); si++)

{

cout << *si << " ";

}

cout << endl;

return 0;

}

 

我们可以用如下语句,代替for循环的输出:

copy(strset.begin(), strset.end(), ostream_iterator(cout, " "));

4.     如何对一些类应用Map容器

map是一个通过键(key)来获得值的。当你用你自己定义的类,而不是一些数据类型(如int),你必须保证自定义的类包含如下函数和操作;

1.

2.

3.      重载运算符’=’

以上三点,是必须的,当然,你也可以添加其他的函数和运算符;

举例:

 

 

#include 

#include

#include

#include

using namespace std;



class CStudent

{

public :

int nStudentID;

int nAge;

public :

//定义一个空的构造函数

CStudent() { }

// Full constructor

CStudent(int nSID, int nA) { nStudentID=nSID; nAge=nA; }

// 定义一个拷贝构造函数

CStudent(const CStudent& ob)

{ nStudentID=ob.nStudentID; nAge=ob.nAge; }

// 重载运算符 =

void operator = (const CStudent& ob)

{ nStudentID=ob.nStudentID; nAge=ob.nAge; }

};



int main(int argc, char* argv[])

{

map <string, CStudent> mapStudent;



mapStudent["Joe Lennon"] = CStudent(103547, 22);

mapStudent["Phil McCartney"] = CStudent(100723, 22);

mapStudent["Raoul Starr"] = CStudent(107350, 24);

mapStudent["Gordon Hamilton"] = CStudent(102330, 22);



// Access via the name

cout << "The Student number for Joe Lennon is " <<

(mapStudent["Joe Lennon"].nStudentID) << endl;



return 0;

}

 

5.     typedef的应用

例如:
typedef set  SET_INT;

typedef SET_INT::iterator SET_INT_ITER

6.

iterator - For any container other than the vector, you can only step one at a time in a forward direction through the container. That is you can only use the ++ operator, not the -- or += operator on it. For vector only you can use any of +=, --, -=, ++, and all the comparison operators <, <=, >, >=, ==, !=.对于大多数的容器,只能应用如下操作符:++,<,<=,>,>=,==,!=;而对于vector向量容器,还可以使用+=, --, -=, ++运算符。
reverse_iterator - If you want to step backwards instead of forwards through a non-vector container, replace iterator with reverse_iterator,begin() with rbegin(), and end() withrend(), ++ will then traverse backwards.
const_iterator - a forward iterator that returns aconst value. Use this if you want to make it clear that this points to a read-only value.
const_reverse_iterator - a reverse iterator that returns aconst value.

7.

算法时应用在模板中的函数。你可以很轻松的对模板容器中的元素进行排序、搜索、操作、交换。

  容器本身并不传递给算法,而是容器的迭代器传递给算法。因此,算法所限制的数据类型是迭代器的数据类型。

举例:

#include   // If you want to use an 

// algorithm this is the header used.

#include // (For Accumulate)

#include

#include

using namespace std;

int testscore[] = {67, 56, 24, 78, 99, 87, 56};

// predicate that eval(int n)

{

return (n >= 60);

}

// predicate that eval(int n)

{

return (n < 60);

}

int main(int argc, char* argv[])

{

int total;

// 用数组初始化向量容器

vector <int> vecTestScore(testscore,

testscore + sizeof(testscore) / sizeof(int));

//生成迭代器vi

vector <int>::iterator vi;



// 整理和输出向量容器里的值

sort(vecTestScore.begin(), vecTestScore.end());

cout << "Sorted Test Scores:" << endl;

for (vi=vecTestScore.begin(); vi != vecTestScore.end(); vi++)

{ cout << *vi << ", "; }

cout << endl;

// min_element 返回一个指向最小值的一个迭代器

vi = min_element(vecTestScore.begin(), vecTestScore.end());

cout << "The lowest score was " << *vi << "." << endl;

// Same with max_element

vi = max_element(vecTestScore.begin(), vecTestScore.end());

cout << "The highest score was " << *vi << "." << endl;

// Use a predicate function to determine the number who passed

//用一个限定函数,来限定传入值的类型;这里限制的是分数

cout << count_if(vecTestScore.begin(), vecTestScore.end(), passed_test) <<

" out of " << vecTestScore.size() <<

" students passed the test" << endl;

// and who failed

cout << count_if(vecTestScore.begin(),

vecTestScore.end(), failed_test) <<

" out of " << vecTestScore.size() <<

" students failed the test" << endl;

// Sum the scores

total = accumulate(vecTestScore.begin(),

vecTestScore.end(), 0);

// Then display the Average

cout << "Average score was " <<

(total / (int)(vecTestScore.size())) << endl;

return 0;

}

 

8.

1.

class CParam
{
string name;
string unit;
vector <double> vecData;
};

2.

class CParam : public vector <double>
{

string name;

string unit;

};

9.

为了创建一个更加复杂的数据结构,你可以在一个模板内创建一个模板。最好先用typedef关键字定义该模板。

举例:

#include 

#include

using namespace std;

typedef vector <int> VEC_INT;

int inp[2][2] = {{1, 1}, {2, 0}};

// Regular 2x2 array to place into the template

int main(int argc, char* argv[])

{

int i, j;

vector <VEC_INT> vecvec;

// if you want to do this in all one step it looks like this

// vector > vecvec;

// Fill it in with the array

VEC_INT v0(inp[0], inp[0]+2); // passing two pointers

// for the range of values to be copied to the vector

VEC_INT v1(inp[1], inp[1]+2);

vecvec.push_back(v0);

vecvec.push_back(v1);

for (i=0; i<2; i++)

{

for (j=0; j<2; j++)

{

cout << vecvec[i][j] << " ";

}

cout << endl;

}

return 0;

}

// Output:

// 1 1

// 2 0

 

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线