STL算法和迭代器

目录

一、算法

(1)简介

(2)STL常见算法

非可变序列算法

可变序列算法

排序算法

二、迭代器

(1)简介

(2)迭代器操作

(3)STL使用自定义对象

三、类中成员函数声明后面接 const


一、算法

(1)简介

算法由头文件<algorithm><numeric><functional>组成

  • <algorithm> 是头文件中最大的,包含的功能有比较、交换、查找、遍历、复制、修改、反转、排序、合并等
  • <numeric> 只包括在序列上进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作
  • <functional> 定义了一些模板类,用来声明函数对象

(2)STL常见算法

  • 非可变序列算法

不直接修改所操作容器内容的算法

find()                    查找容器元素

find_if()                条件查找容器元素

#include <algorithm>                  
//for_each函数的头文件

//find()
vector<int> v1;             
for(int i=0;i<10;i++)
{
    v1.push_back(2*i);
}
for_each(v1.begin(),v1.end(),MyPrint);                          //MyPrint为之前定义的函数
vector<int>::iterator it1 = find(v1.begin(),v1.end(),5);        //查找成功返回迭代器,失败返回v1.end()

//find_if()
bool DivBy5(int x)
{
    return x%5? 0:1;
}
vector<int>::iterator it2 = find_if(v1.begin(),v1.end(),DivBy5);   //返回第一个能被5整除的元素

count()                 统计元素的个数

count_if()             条件统计元素的个数

//count()
int num1 = count(v1.begin(),v1.end(),3);

//count_if()
int num2 = count(v1.begin(),v1.end(),DivBy5);          //第3个参数是条件函数

search()              子序列搜索,返回子序列在父序列中起始位置

search_n()           重复元素的子序列搜索

//search()
vector<int> v2;                //子序列
for(int i=0;i<2;i++)
{
    v2.push_back(i+8);
}
vector<int>::iterator it3 = search(v1.begin(),v1.end(),v2.begin(),v2.end());    
//前2个参数是搜索序列的范围,后2个参数是子序列范围

//search_n()
vector<int>::iterator it4 = search(v1.begin(),v1.end(),3,8);
                                          //在v1中搜索子序列 8 8 8 
  • 可变序列算法

修改所操作容器内容的算法

copy()                   元素复制

transform()           元素变换,也是复制,按照某种方案复制

//copy()
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(5);

list<int> l;
l.push_back(2);
l.push_back(4);
l.push_back(6);
l.push_back(8);

copy(v.begin(),v.end(),l.begin());    //把v拷贝到l的头部,会覆盖l的数据

//transform(),按照规则拷贝
int square(int x)
{
    return x*x;
}

transform(v.begin(),v.end(),l.begin(),square);    //把v的平方拷贝到l的头部,会覆盖l的数据

replace()              替换元素

replace_if()          条件替换

//replace()
replace(v.begin(),v.end(),5,100);    //将所有5替换成100

//replace_if()
bool odd(int x)
{
    return x%2;
}
replace_if(v.begin(),v.end(),odd,100);   //将奇数替换成100

remove()              删除元素

remove_if()          条件删除

//remove()           
remove(v.begin(),v.end(),5);        //删除值为5的元素,但数组大小不变
                                    //删除前 1  3  5  7
                                    //删除后 1  3  7  7

//remove_if()
bool even(int x)
{
    return x%2?0:1;
}
remove_if(v.begin(),v.end(),even)   //删除奇数
                                    //删除前 1  2  3  4  5  6  7  8  9  10
                                    //删除后 1  3  5  7  9  6  7  8  9  10

 

  • 排序算法

sort()                    普通排序

make_heap()       将一个区间转换成堆

sort_heap()          对堆进行排序,排序后就不是堆了

//sort()                    
sort(v.begin(),v.end());              //参数为要排序的区间,默认升序排列  

//make_heap()
make_heap(v.begin(),v.end());         //将区间转换成大根堆

//sort_heap()         
sort_heap(v.begin(),v.end());         //对堆进行排序,默认升序排列

 

二、迭代器

(1)简介

迭代器用于指向容器中的一个元素,有const非const两种

通过迭代器可以读取它指向的元素,通过非const迭代器可以修改它指向的元素

不同容器支持的迭代器功能强弱不同,迭代器功能强弱决定了该容器是否支持STL中的某种算法


定义迭代器:

容器类名:: iterator  变量名 ,如 vector<int>::iterator  v;

容器类名:: const_iterator  变量名 ,如 vector<int>::const_iterator  v;

访问迭代器指向的元素:

* 迭代器变量名


迭代器功能由弱到强分为5种

1.输入:Input iterators 提供对数据的只读访问

1.输出:Output iterators 提供对数据的写访问

2.正向:Forward iterators 提供读写操作,并能向前推进迭代器

3.双向:Bidirectional iterators 提供读写操作,并能向前和向后操作

4.随机:Random access iterators 提供读写操作,并能在数据种随机移动(能使用[ ]操作符)

编号大的迭代器拥有编号小的迭代器的功能,能当编号小的迭代器使用


不同迭代器能进行的操作

所有迭代器: ++p,p++

输入迭代器:*p,p=p1,p==p1,p!=p1

输出迭代器:*p,p=p1

正向迭代器:上面全部

双向迭代器:上面全部,--p,p--

随机访问迭代器:上面全部,

                             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不支持

(2)迭代器操作

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

int arr[] = {11,12,13,14,15,16,17,18,19,20};
vector<int> v(arr,arr+9);
vector<int>::const_iterator it1 = v.begin();        //常量迭代器,指向第一个元素11
vector<int>::const_iterator it2 = v.cbegin();       //常量迭代器,指向第一个元素11
                                                    //cbegin()和cend()方法,返回一个const的迭代器,不能用于修改元素
vector<int>::iterator it3 = v.begin();
*it3 = 10;                                          //修改第一个元素值为10
it3++;                     //指向第二个元素

//迭代器的比较是按照迭代器指向的值来进行比较                                          

(3)STL使用自定义对象

向vector,deque,list,stack,queue添加自定义对象,实际是将对象复制到容器中,要调用对象的拷贝函数;

如果定义了拷贝函数就调用定义的拷贝函数,否则就调用默认的拷贝函数;

向set和map容器添加自定义对象也是将对象复制到容器中,不同的是set和map容器要实现比较器函数

  • vector容器
class member
{
private:
   string m_str;
   int m_id;
public:
   member(const string str,const int id):m_str(str),m_id(id){};    //构造函数
   void MyPrint()
   {
      cout<< m_str << ":" << m_id;
   }
};

vector<member> v1;
v1.push_back(member("123",1));
v1.push_back(member("456",2));

vector<member> v2(v1);        //用v1初始化v2
vector<member>::iterator it = v2.begin();
it-> MyPrint();               //打印结果为123:1
  •  set容器
class student
{
private:
   int s_str; string s_id;
public:
   student(const int id,const string str)
   {
      s_id= id; s_str = str;
   }
   void MyPrint()const             //const成员函数
   {
      cout<< s_str << ":" << s_id;
   }
};

//小于比较器
struct stuFun         
{
   bool operator()(const student& stu1,const student& stu2)
   {
      return(stu1.s_id < stu2.s_id)
   }
};

set<student,stuFun> s1;
s1.insert(student(7,"小A"));
s1.insert(student(5,"小B"));
s1.insert(student(3,"小C"));
s1.insert(student(1,"小D"));      //按id进行升序排列

set<student,stuFun> s2(s1);
set<student,stuFun>::iterator it = s2.begin();
it-> MyPrint();                   //打印结果为 小D:1

 

 

三、类中成员函数声明后面接 const

  • const 表示对类中成员函数属性的声明
  • 表示不会修改类中的数据成员;
  • 在编写const成员函数时,若不慎修改了数据成员,或者调用了非const成员函数,编译器报错;
class S
{
private:
    int num;
    int data[100];
public:
    void Push(int elem);
    int Pop(void);
    int GetCount(void) const;     //const成员函数
};

//注意:在实现的时候需要带有const修饰
int S::GetCount(void)const                 
{
    ++num;          //编译错误,企图修改数据成员num
    Pop();          //编译错误,企图调用非const函数
    return num;
}

类中被const声明的成员函数只能访问const成员函数,而非const函数可以访问任意的成员函数,包括const成员函数

类中被const声明的成员函数不可以修改对象的数据,不管对象是否具有const性质,它在编译时,会检查是否修改成员数据

加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值