【c++】标准库

【c++】标准库

一.  标准库概述

二.迭代器

三.算法

    3.1.数据编辑算法

    3.2.查找算法

    3.3.比较算法

    3.4.排序相关算法

    3.5.计算相关算法

四.函数对象

五.适配器

六.字符串库

 参考:《c++从入门到精通》人民邮电出版社



一.  标准库概述

        C++标准库就好像设计图象时的图库一样,为c++程序员提供了可扩展的基础性框架,为程序设计带来了便利。本章介绍标准库的组成,STL中的迭代器、算法、函数对象、适配器以及字符串库等。

1.认识标准库

    C++标准分为两部分:c++语言本身和c++标准库。

    C++模板是对c++语言的一种扩展,模板是根据类型参数来产生函数和类的机制,也称模板为“参数化的类型”。使用模板,可以设计一个对多种数据类型进行操作的类,而不需要为每种类型建立一个单独的类。

    标准库中的一切几乎都是模板。

2.标准库的组成

    C++中标准库中的主要组件如图所示:

                

    (1) 标准模板库STL:是基于模板的,是c++标准库中的重要组成部分。STL包括5大组件:容器、算法、迭代器、函数对象、适配器。

    STL是基于数据和操作分离的,容器处理数据,算法数据操作,而迭代器则将它们结合起来。STL包含了很多在计算机科学领域里常用的基本数据结构和基本算法。

    (2) C标准函数库:基本保持了与原C语言程序库的良好兼容。

    (3) 语言支持:包含一些标准类型的定义以及其他特性的定义。

    (4)诊断:用于程序诊断和报错,包含异常处理、断言、错误代码 三部分。

    (5)通用工具:例如,动态内存管理工具,日期、时间处理工具。

    (6)字符串:用来代表和处理文本。文本是一个string对象,可被看作是一个字符序列或者是容器。

    (7)输入、输出:对原有标准库中的iostream进行模板化的部分,提供对c++程序输入输出的基本支持。

    (8)数值:数字处理

    (9)国际化:采用locale和facet为程序提供国际化支持,包括对各种字符集的支持,日期和时间的表示,数值和货币的处理,等等。

二.迭代器

    每个容器都有自己的迭代器,可以把迭代器看作一个容器所使用的特殊指针,可以存取容器内存储的数据。

迭代器的功能表:

使用迭代器可对容器中的数据进行操作。下表列出了主要的操作,其中iter和iter1表示迭代器。


迭代器核心代码:

list<int>::iterator list1_iterator ;//定义列表的迭代器,相当于指针  
for(list1_iterator=list1.begin(); list1_iterator !=list1.end(); list1_iterator++ )  
    {  
        if(*list1_iterator ==100 )  cnt++;  

    }  

. 算法

    算法是STL的一个重要组成部分,它提供了数据处理函数,可用于操作各种容器。STL的算法被定义在<algorithm>头文件中。

    STL中使用迭代器作为算法与容器间的媒介,算法要求的迭代器一定要与容器的迭代器相匹配,如sort算法使用随机迭代器,而list容器的迭代器仅为向前迭代器,所以sort算法无法在list容器上使用。

1.数据编辑算法

    数据编辑算法用来对容器内的数据进行编辑操作,如数据的填充、复制、合并、删除和替换等。

函数

功能

格式

说明

fill

用给定值初始化一个范围

Template<class ForwardIterator, class T>

void fill( ForwardIterator first , ForwardIterator last,

const T &value);

用value值填充容器[first,last]范围

copy

用于容器之间数据的复制

Template<class InputIterator,class OutputIterator >

OutputIterator copy(InputIterator first,  InputIterator  last,

OutputIterator  result);

返回值:是迭代器类型,它指向新复制容器的末尾

复制容器【first,last】范围内的元素到另一个容器的以result为起始的指定位置处。

me

r

ge

用于将两个已排序的序列合并为第三个序列

Template<class InputIterator1, class InputIterato2r,class OutputIterator >

OutputIterator merge(InputIterator1 first1,  InputIterator1  last1, InputIterator2  first2,  InputIterator2  last2,

OutputIterator  result);

将容器1的【first1,last1】与容器2的【first2,last2】范围内的对象合并后的有序序列存放在以result为起始的指定位置处,容器1的数据在前。

r

emove

用于移除容器某一范围的数据

Template<class ForwardIterator, class T>

void  remove( ForwardIterator first , ForwardIterator last,

const T &value);

返回值:返回容器新末端的迭代器

注意:不是将该元素移除,而是将该元素用后边的元素覆盖了,因此remove后容器长度不变,而未被移除的元素将会向前复制,后边多余的元素将不会移除。

移除【first,last】范围内的值是value的所有元素。

r

ep

l

ace

用于将容器某范围内的元素值替换

Template<class ForwardIterator, class T>

void  remove( ForwardIterator first , ForwardIterator last,

const T & old_value, const T & new_value );

将【first,last】范围内的old_value值用new_value来替换。

【编程实例】

    分别编程实现上述五种算法的应用。都需用到一个显示函数show(),特将其定义为函数模板,如下:

template<class T>
void show(T &a)
{
    if(a.empty()) cout<<"没有元素"<<endl;
    else
    {
        T::iterator iter; //在gcc下编译未通过
        for(iter=a.begin();iter!=a.end();++iter)
        {
            cout<<*iter<<" ";
        }
        cout<<endl;
    }
}

注意,上述T::iterator iter; //在gcc下编译未通过

需改为class T::iterator iter; //编译通过

1. Fill

核心代码:

vector<char>v1(10);//声明向量容器
cout<<"fill:使用‘A’填充容器"<<endl;
fill(v1.begin(),v1.end(),'A');
show(v1);

运行结果:

2. Copy

核心代码:

char a[]={'B','B','B','B'};
vector<char> v2(a,a+4);  //用数组a初始化v2
cout<<"copy:将v2复制给v1"<<endl;
copy(v2.begin(),v2.end(),v1.begin()+3 );
show(v1);

运行结果:

3. Remove

核心代码:

vector<char>::iterator iter1;
cout<<"remove:移除v1中的‘A’"<<endl;
iter1=remove(v1.begin(),v1.end(),'A');
show(v1);

运行结果:

4. Erase

核心代码:

cout<<"erase:删除末端元素"<<endl;
v1.erase(iter1,v1.end() );
show(v1);

运行结果:

5. Replace

核心代码:

cout<<"replace:替换B为C"<<endl;
replace(v1.begin(),v1.end(),'B','C');
show(v1);

运行结果:

2.查找算法

名称

功能

格式

说明

Find

用于在某范围内查找数据

Template<class InputIterator,class T >

inputIterator find(InputIterator first,  InputIterator  last,  const T & value);

返回值:返回值是迭代器类型,若找到该数据,则指向数据在容器中第一次出现的位置,否则指向结果序列的尾部。

在【first,last】范围内查找value是否出现

search

用于两个范围的查找

Template<class forwardIterator1, class forwardIterato2 >

forwardIterator1 search(

forwardIterator1 first1, 

forwardIterator1  last1,

forwardIterator2  first2,

forwardIterator2  last2

);

返回值:返回值是迭代器类型,若找到该数据,则指向数据在容器中第一次出现的位置,否则指向结果序列的尾部。

在【first1, last1】范围内查找另一容器  

【Frist2 ,last2】是否存在

1. Find

核心代码:

char a[]={'A' ,'B', 'C','D' ,'E', 'F','G' ,'H','G','F'};
vector<char> v1(a,a+8);//声明向量容器
vector<char>::iterator iter;
iter=find(v1.begin(),v1.end(),'D');
show(v1);
cout<<"find:在v1中找D"<<endl;

if(iter !=v1.end() ) //说明找到了
cout<<"D的位置为:"<<int(iter -v1.begin())<<endl;
else cout<<"没找到"<<endl;

运行结果:

2. search

核心代码:

cout<<"v1:";
show(v1);
cout<<"v2:";
show(v2);
cout<<"search:在v1中找V2"<<endl;

iter=search(v1.begin(),v1.end(),v2.begin(),v2.end());
if(iter!=v1.end() )  //说明找到了
cout<<"v2的位置为:"<<int(iter - v1.begin())<<endl;
else cout<<"没找到"<<endl;
return 0;

运行结果:

3.比较算法


【编程实例】

// 比较算法.cpp

#include<iostream>
#include<algorithm>
#include<vector>
#include<stdio.h>
using namespace std;

 // 函数模板
template<class T>
void show(T &a)
{
    if(a.empty()) cout<<"没有元素"<<endl;
    else
    {
        class T::iterator iter;
        for(iter=a.begin();iter!=a.end();++iter)
        {
            cout<<*iter<<" ";
        }
        cout<<endl;
    }
}


int main(int argc,char *argv[])
{
    char a[]={'A' ,'B', 'C','D' ,'E', 'F','G' ,'H','G','F'};
    vector<char> v1(a,a+8);//声明向量容器
    vector<char> v2(a+2,a+5);//声明向量容器
    vector<char> v3(a,a+8);//声明向量容器

    bool res;
    cout<<"v1:";
    show(v1);
    cout<<"v2:";
    show(v2);
    cout<<"equal:v1与v2"<<endl;
    res=equal(v1.begin(),v1.end(), v2.begin());
    if(res )  //说明找到了
        cout<<"相等"<<endl;
    else cout<<"不相等"<<endl;


    cout<<endl;
    pair<vector<char>::iterator , vector<char>::iterator> pair1 ;
    cout<<"v1:";
    show(v1);
    cout<<"v3:";
    show(v3);
    cout<<"mismatch:v1与v3"<<endl;
    pair1=mismatch(v1.begin(),v1.end(),v2.begin() );
    if( pair1.first ==v1.end()  && pair1.second ==v2.end() )  //说明找到了
        cout<<"匹配"<<endl;
    else cout<<"不匹配:"<<(int)(*pair1.first) << " "<<(int)(*pair1.second) <<endl;
    {
    //printf("%c\n",*pair1.first);
    //printf("%c\n",*pair1.second);
    }
    return 0;
}

运行结果:

注意:此处有问题?mismatch!

4. 排序相关算法


【编程实例】

//排序算法.cpp

#include<iostream>
#include<algorithm>
#include<vector>
#include<stdio.h>
using namespace std;

 // 函数模板
template<class T>
void show(T &a)
{
    if(a.empty()) cout<<"没有元素"<<endl;
    else
    {
        class T::iterator iter;
        for(iter=a.begin();iter!=a.end();++iter)
        {
            cout<<*iter<<" ";
        }
        cout<<endl;
    }
}


int main(int argc,char *argv[])
{
    char a[]={'G','F','A' ,'B', 'C','D' ,'E', 'F','G' ,'H','G','F'};
    vector<char> v1(a,a+10);//声明向量容器
    //vector<char> v2(a+2,a+5);//声明向量容器


    cout<<"v1:";
    show(v1);
    cout<<"排序sort:v1"<<endl;
    sort(v1.begin(),v1.end());
    show(v1);

    cout<<"取逆reverse:v1"<<endl;
    reverse(v1.begin(),v1.end());
    show(v1);


    return 0;
}

运行结果:

5.计算相关算法

        

. 函数对象

    在许多算法中,经常使用函数对象对容器中的数据进行大小比较、逻辑运算、数学运算等操作。

1. 函数对象的应用

    使用系统函数对象时,必须引入functional头文件。

    函数对象是一个由模板类产生的对象,该模板类只有一个用于重载的operator()函数。

    使用函数对象的方法:

        (1) 先通过调用带数据类型的默认构造函数建立一个函数对象

        (2) 然后在容器或算法中使用该函数对象

    如:

            

2. 自定义函数对象

    自定义函数对象的使用有两种形式:建立函数对象类和建立函数模板对象类。

(1) 建立函数对象类

class square1
{
public :
     operator() (int i)  {
            return i*i;
}
}

(2)  简历模板函数对象类

Template<classT>
class square2
{
public :
       operator() (T i)  {
              return i*i;
}
}

自定义函数对象建立后,该函数对象的使用和系统的函数对象的使用相同。如下:

. 适配器

    适配器和顺序容器相结合,提供了堆栈、队列和优先队列等功能。

    适配器有3种类型:容器适配器、迭代适配器、函数对象适配器。

1. 容器适配器

.

2.  stack容器

. 字符串库

    字符串库在C++标准中有两个头文件:

        ----  c库头文件<string.h>,是操作字符串的函数库

        ----  c++库头文件<string>, 它是操作字符串的string类

    本节将对后者进行简单介绍。

 1、string对象的定义和初始化

有以下5种方法:






2.字符串的读写

iostream标准库可以用来读写c++的标准数据类型,也可以用来读写string对象。


【编程实现】输入输出string

//字符串操作.cpp
#include<iostream>
#include<string>
using namespace std;

int main()
{

string s1,s2,s3;
cout<<"input s1:"<<endl;
cin>>s1;     // input s1
cout<<"s1:"<<s1<<endl;

cout<<"input s2:"<<endl;
getline(cin,s2);  //默认遇到换行符结束
cout<<"s2:"<<s1<<endl;

cout<<"input s3:"<<endl;
getline(cin, s3,'5');  //遇到‘5’读取结束
cout<<"s3:"<<s3<<endl;

return 0;
}

运行结果:


3.字符串的赋值

字符串的赋值操作有:赋值函数assign( ) 和 “=”运算符。

(1)assign()函数


 



(2)“=”运算符

string类对“=”进行了重载,可直接使用。


4. 字符串的比较

用于字符串的比较的方法有两种:关系运算符和compare()函数。

(1)关系运算符


例如:

string s1("abcdefg");
string s2("aedfg");
bool i=s1<s2 ;    // 则i 的值为 0

(2)compare()函数



5.字符串的连接

字符串的连接有两种形式:append()函数 和 “+=”复合赋值运算符。

(1)append()函数

   两种方式,如下:



(2)“+=”复合赋值运算符



6.字符串特性描述



7.字符串操作

(1)【】下标操作符

 
 
string s1("helo");
char  c= s1[1] ;  //则c='e'

(2)at

string s1("helo");
char  c= s1.at(1) ;  //则c='e'

(3) c_str()

返回以null 终止的字符串。

string s1("help you");
string s2=s1.c_str() ;  //则c="help you"

8.字符串对象中 字符的处理


 -------------------------------------------         END      -------------------------------------


猜你喜欢

转载自blog.csdn.net/u012679707/article/details/80302547