C++面向对象程序设计(八)——标准模板库STL(一)

C++面向对象程序设计(八)——标准模板库STL(一)


本文是中国大学MOOC,北京大学 程序设计与算法C++面向对象程序设计第八周笔记。本课程学习的 github仓库欢迎Fork

string类

来自模板类typedef basic_string<char> string

在使用前要包含头文件<string>

#include<iostream>
#include<string>
using namespace std;

int main()
{
    string s1("hello");
    cout << s1 <<endl;
    string s2(8,'x');
    cout << s2 <<endl;
    string month = "March";
    cout << month << endl;
    string s;
    s = 'n';
    cout << s<<endl;
    return 0;
}
//输出:
//Hello
//xxxxxxxx
//March
//n    

可以使用成员函数length()读取长度,支持cingetline(cin,s)

可以使用=赋值,使用assign成员函数复制

string s1("cat"),s2;
s2 = s1;
string s1("cat"),s3;
s3.assign(s1);
string s1("catpig"),s3;
s3.assign(s1,1,3);

单个字符的复制

s2[5] = s1[3] ='a';

逐个访问对象中字符

string s1("Hello");
for(int i = 0;i<s1.length();i++)
    cout<<s1.at(i)<<endl;
//成员函数at会做范围检查,如果超出范围会出现out_of_range异常,而[]不会检查

可以使用+运算符连接字符串

string s1("good"),s2("morning");
s1 += s2;
cout << s1;

用成员函数append连接字符串

string s1("good"),s2("morning");
s1.append(s2);
cout << s1;
s2.append(s1,3,s1.size());
cout << s2;

string间可以比较大小>=

还可以使用compare比较string大小

求子串substr

string s1("hello world"),s2;
s2 = s1.substr(4,5)//下标4开始长度5个字符
cout << s2 << endl; 

交换swap

s1.swap(s2);//两个字符串内容交换

正着查找find

s1.find("lo");
s1.find("lo",2);//下标2开始找

倒着查找rfind

s1.rfind("lo");

find_first_of

s1.find_first_of("abcd");//从前向后查找abcd中任意一个第一次出现的地方

find_last_of

s1.find_last_of("abcd")//查找最后一次出现的地方

find_first_not_of

s1.find_first_not_of("abcd");//从前向后查找不在abcd中的字符任意一个第一次出现的地方

删除string中的字符使用成员函数erase()

s1.erase(5);//去掉下标5及之后的字符

替换string中的字符

成员函数replace()

s1.replace(2,3,"haha");//将下标2开始的3个字符换成"haha"

成员函数insert()

s1.insert(5,s2)//s2插入到下标5的位置

成员函数c_str()

转换成C语言式的char *字符串

s1.c_str();	//返回const char  *

成员函数data

返回char *字符串,不带const

字符串流处理

我们可以使用istringstreamostringstream进行字符串上的输入输出,也称为内存输入输出

#include<string>
#include<iostream>
#include<sstream>

string input("Input test 123 4.7 A");
istringstream inputString(input);
string string1,string2;
int i;
double d;
char c;
inputString >> string1 >> string2 >> i >>d >>c;
cout << string1 << endl <<string2 <<endl;
cout << i <<endl <<d <<endl <<c <<endl;
long L;
if(inputString >> L) cout <<"long\n";
else cout << "empty\n";

/*输出
Input
test
123
4.7
A
empty
*/
ostringstream outputString;
int a =10;
outputString << "This" << a << "ok" << endl;
cout << outputString.str();
/*
输出
This 10ok
*/

标准模板库STL概述(一)

C++语言的核心优势之一就是软件的重用

主要体现在:面向对象的思想:继承,多态,标准类库

泛型程序设计思想 :模板机制,STL

基本概念

容器:可容纳各种数据类型的通用数据结构,是类模板

容器分为三种

顺序容器vector,deque,list
vector 动态数组

头文件<vector>

元素在内存中连续存放,随机存取任何元素都能在常数时间完成。在尾端增删元素具有较佳性能

deque 双向队列

元素在内存连续存放。随机存取任何元素都能在常数时间完成。在两端增删元素具有较佳性能

list 双向链表

元素在内存不连续存放。在任何位置增删元素都能在常数时间完成,不支持随机存取

关联容器set,multiset,map,multimap

元素是排序的,插入任何元素都按相应的排序规则来确定其位置。

在查找时具有良好的性能

通常以平衡二叉树方式实现,插入和检索时间都是logN

set/multiset 集合

头文件,set中不允许相同元素,multiset允许存在相同的元素

map/multimap

map与``set的不同在于map中存放的元素有且仅有两个成员变量,一个名为first,另一个名为second,map根据first`值对元素进行小到大排序,可快速根据first检索元素

map与``multimap的不同在于是否允许相同的firsr`值的元素

容器适配器stack,queue,priority_queue
stack 栈

头文件 是项的有限序列,满足序列中被删除,检索和修改的项只能是最近插入序列的项。后进先出

queue 队列

插入只可以在尾部进行,删除,检索和修改只允许从头部进行。先进先出

priority_queue

头文件

优先级队列,最高优先级元素总是第一个出列

对象被插入容器中时,被插入是对象的一个复制品。许多算法,比如排序,查找,要求对容器中的元素进行比较,有的容器本身是排序的,所以放入容器对象所属的类,往往还应该重载==<运算符

顺序容器和关联容器中都有的成员函数

begin返回指向容器中第一个元素的迭代器

end返回指向容器中最后一个元素后面的位置的迭代器

rbegin返回指向容器中最后一个元素的迭代器

rend返回指向容器中第一个元素前面的位置的迭代器

erase从容器中删除一个或几个元素

clear从容器中删除所有元素

顺序容器的常用成员函数

front返回容器中第一个元素的引用

back返回容器中最后一个元素的引用

push_back在容器末尾增加新元素

pop_back删除容器末尾的元素

erase删除迭代器指向的元素,或删除一个区间,返回被删除元素后面那个元素的迭代器

迭代器:可用于依次存取容器中元素,类似于指针

算法:用来操作容器中元素的函数模板

迭代器

容器类名::iterator 变量名;
容器类名::const_iterator 变量名;

访问一个迭代器指向的元素:

* 迭代器变量名

用于指向顺序容器和关联容器中的元素。用法和指针类似。有const和非const两种。通过迭代器可以读取它指向的元素。通过非const迭代器能修改其指向的元素。迭代器可以执行++操作

#include<venctor>
#include<iostream>
using namesapce std;

int main()
    vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	vector<int>::const_iterator i;
	for(i = v.begin();i != v.end();++i)
        cout << *i << ",";
	cout << endl;
	vector<int>::reverse_iterator r;
	for( r =v.rbegin();r != v.rend(); r++)
        cout << * r <<",";
	cout<<endl;
	vector<int>::iterator j;
	for(j=v.begin();j!=v.end();j++)
        *j = 100;
	for(i=v.begin();i!=v.end();i++)
        cout << * i <<",";
}

/*输出结果
1,2,3,4,
4,3,2,1,
100,100,100,100,

双向迭代器

++p,p++使p指向容器中下一个元素

–p,p--是p指向容器中上一个元素

*p取p指向的元素

p = p1赋值

p == p1,p! = p1判断是否相等,不等

随机访问迭代器

双向迭代器所有操作都可以使用

p+=ip向后移动i个元素

p-=ip向前移动i个元素

p+i值为指向p后面第i个元素的迭代器

p-i值为指向p前面的第i个元素的迭代器

p[i]值为p后面的第i个元素的引用

p<p1,p<=p1,p>p1,p>=p1

容器容器上迭代器类别
vector随机访问
deque随机访问
list双向
set/multiset双向
map/multimap双向
stack不支持
queue不支持
priority_queue不支持

vector迭代器是随机迭代器

遍历vector的几种做法(queue同)

vector<int> v(100);
int i;
for(i=0;i<v.size();i++)
    cout << v[i];//根据下标随机访问
vector<int>::const_iterator ii;
for(ii = v.begin();ii != v.end();ii++)
    cout << *ii;
for(ii = v.begin();ii<v.end();ii++)
    cout << *ii;

list迭代器是双向迭代器

list<int> v;
list<int>::const_iterator ii;
for(ii = v.begin;ii!=v.end();++ii)
    cout << *ii;

双向迭代器不支持<,list没有[]成员函数

算法

是一个个函数模板,往往在中定义

find()

template<class InIt,class T>
InIt	find(InIt first,InIt last,const T&val);

查找区间是[first,last),用==判断相等

#include<vector>
#include<algorithm>
#include<iostream>

using namespace std;

int main()
{
    int array[10] = {10,20,30,40};
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    vector<int>::iterator p;
    p = find(v.begin(),v.end(),3)
    if(p!=v.end())
        cout << *p << endl;//输出3
   	p = find(v.begin(),v.end(),9);
    if(p==v.end())
        cout << 'not found'<<endl;
    p = find(v.begin()+1,v.end()-2,1);
    if(p!=v.end())
        cout << *p <<endl;
    int * pp = find(array,array+4,20);
    cout << *pp << endl;
    
}

vector

vector实现二维数组

vector<vector<int> >v(3);

deque双向队列

所有vector的操作都适合dequedeque还有push_frontpop_front操作

list双向链表

不支持随机存取,任何位置插入删除都是常数时间

push_front在前面插入

pop_front删除前面元素

sort排序

remove删除和指定值相等的所有元素

unique删除和前一个元素相同的元素

merge合并两个链表,并清空被合并的那个

reverse颠倒链表

splice指定位置前面插入另一个链表的一个或多个元素,并在另一个链表中删除被插入的元素

函数对象

若一个类重载了运算符(),那么该类的对象就是函数对象

class CMyAverge{
    public:
    	double operator() (int a1,int a2,int a3)
        {
            return (double)(a1+a2+a3)/3;
        } 
    CMyAverage average;
    cout << average(3,2,3);
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈沧夜

打个赏,让我买瓶可乐喝呗~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值