浅析STL中的常用算法

 更新时间:2013年09月25日 09:57:59   作者:  
以下是对STL中的常用算法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助

一、非变异算法

是一组不破坏操作数据的模板函数,用来对序列数据进行逐个处理、元素查找、子序列搜索、统计和匹配。非变异算法具有极为广泛的适用性,基本上可应用与各种容器。

1查找容器元素find

它用于查找等于某值的元素。它在迭代器区间[first,last)(闭开区间)上查找等于value值的元素,如果迭代器i所指的元素满足*i=value,则返回迭代器i;未找到满足条件的元素,返回last。函数原型:find( v1.begin(), v1.end(), num_to_find );

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

int num_to_find = 6;

vector<int> v1;

for( int i = 0; i < 10; i++ )

v1.push_back(2*i);

vector<int>::iterator result;

result = find( v1.begin(), v1.end(), num_to_find );

if( result == v1.end() )

cout << "未找到任何元素匹配 " << num_to_find << endl;

else

cout << "匹配元素的索引值是 " << result-v1.begin() << endl;

}


2条件查找容器元素find_if

利用返回布尔值的谓词判断pred,检查迭代器区间[first,last)(闭开区间)上的每一个元素,如果迭代器i满足pred(*i)=true,表示找到元素并返回迭代值i(找到的第一个符合条件的元素);未找到元素,返回末位置last。函数原型:find_if(v.begin(),v.end(),divby5);

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

bool divby5(int x)

{

return x%5?0:1;

}

void main()

{

vector<int> v(20);

for(int i=0;i<v.size();i++)

{

v[i]=(i+1)*(i+3);

cout<<v[i]<<' ';

}

cout<<endl;

vector<int>::iterator ilocation;

ilocation=find_if(v.begin(),v.end(),divby5);

if(ilocation!=v.end())

cout<<"找到第一个能被5整除的元素:"<<*ilocation<<endl<<"元素的索引位置是: "<<ilocation-v.begin()<<endl;

}


3统计等于某值的容器元素个数count

list<int> l;
count(l.begin(),l.end(),value)

4条件统计count_if

count_if(l.begin(),l.end(),pred)。谓词pred含义同find_if中的谓词。例子可以参考例2.

5子序列搜索search

search算法函数在一个序列中搜索与另一序列匹配的子序列。参数分别为一个序列的开始位置,结束位置和另一个序列的开始,结束位置。

函数原型:search(v1.begin(),v1.end(),v2.begin(),v2.end());

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v1;

cout<<"v1:";

for(int i=0;i<5;i++)

{

v1.push_back(i+5);

//注意:v1定义时没有给定大小,因此这里不能直接使用赋值语句。

cout<<v1[i]<<' ';

}

cout<<endl;

vector<int> v2;

cout<<"v2:";

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

{

v2.push_back(i+7);

cout<<v2[i]<<' ';

}

cout<<endl;

vector<int>::iterator ilocation;

ilocation=search(v1.begin(),v1.end(),v2.begin(),v2.end());

if(ilocation!=v1.end())

cout<<"v2的元素包含在v1中,起始元素为"<<"v1["<<ilocation-v1.begin()<<']'<<endl;

else

cout<<"v2的元素不包含在v1中"<<endl;

}


6重复元素子序列搜索search_n

search_n算法函数搜索序列中是否有一系列元素值均为某个给定值的子序列。函数原型:search_n(v.begin(),v.end(),3,8),在v中找到3个连续的元素8

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v;

v.push_back(1);

v.push_back(8);

v.push_back(8);

v.push_back(8);

v.push_back(6);

v.push_back(6);

v.push_back(8);

vector<int>::iterator i;

i=search_n(v.begin(),v.end(),3,8);

if(i!=v.end())

cout<<"在v中找到3个连续的元素8"<<endl;

else

cout<<"在v中未找到3个连续的元素8"<<endl;

}


7最后一个子序列搜索find_end

函数原型find_end(v1.begin(),v1.end(),v2.begin(),v2.end());在V1中要求的位置查找V2中要求的序列。

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

 

void main()

{

vector<int> v1;

v1.push_back(-5);

v1.push_back(1);

v1.push_back(2);

v1.push_back(-6);

v1.push_back(-8);

v1.push_back(1);

v1.push_back(2);

v1.push_back(-11);

vector<int> v2;

v2.push_back(1);

v2.push_back(2);

vector<int>::iterator i;

i=find_end(v1.begin(),v1.end(),v2.begin(),v2.end());

if(i!=v1.end())

cout<<"v1中找到最后一个匹配v2的子序列,位置在" <<"v1["<<i-v1.begin()<<"]"<<endl;

}


二、变异算法

是一组能够修改容器元素数据的模板函数。copy(v.begin(),v.end(),l.begin());将v中的元素复制到l中。

1 元素复制copy

复制代码 代码如下:

#include <vector>

#include <list>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

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);

l.push_back(10);

copy(v.begin(),v.end(),l.begin());

list<int>::iterator i;

for(i=l.begin();i!=l.end();i++)

cout<<*i<<' ';

cout<<endl;

}


2 元素变换transform改变

函数原型:transform(v.begin(),v.end(),l.begin(),square);也是复制,但是要按某种方案复制。

复制代码 代码如下:

#include <vector>

#include <list>

#include <algorithm>

#include <iostream>

using namespace std;

 

int square(int x)

{

return x*x;

}

void main()

{

vector<int> v;

v.push_back(5);

v.push_back(15);

v.push_back(25);

list<int> l(3);

transform(v.begin(),v.end(),l.begin(),square);

list<int>::iterator i;

for(i=l.begin();i!=l.end();i++)

cout<<*i<<' ';

cout<<endl;

}


3 替换replace

replace算法将指定元素值替换为新值。

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v;

v.push_back(13);

v.push_back(25);

v.push_back(27);

v.push_back(25);

v.push_back(29);

replace(v.begin(),v.end(),25,100);

vector<int>::iterator i;

for(i=v.begin();i!=v.end();i++)

cout<<*i<<' ';

cout<<endl;

}


输出结果为13 100 27 100 29

4 条件替换replace_if

函数原型:replace_if(v.begin(),v.end(),odd,100);

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

bool odd(int x)

{

return x%2;

}

void main()

{

vector<int> v;

for(int i=1;i<10;i++)

v.push_back(i);

replace_if(v.begin(),v.end(),odd,100);

vector<int>::iterator ilocation;

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

}


5 n次填充fill_n

函数原型fill_n(v.begin(),5,-1);向从v.begin开始的后面5个位置跳入-1

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v(10);

fill_n(v.begin(),5,-1);

vector<int>::iterator ilocation;

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

}


输出结果:-1 -1 -1 -1 -1 0 0 0 0 0

6 随机生成n个元素generate

函数原型:generate_n(v.begin(),5,rand);向从v.begin开始的后面5个位置随机填写数据。

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v(10);

generate_n(v.begin(),5,rand);

vector<int>::iterator ilocation;

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

}


7 条件移除remove_if

返回值相当于移除满足条件的元素后形成的新向量的end()值。

函数原型:remove_if(v.begin(),v.end(),even);

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

bool even(int x)

{

return x%2?0:1;

}

void main()

{

vector<int> v;

for(int i=1;i<=10;i++)

v.push_back(i);

vector<int>::iterator ilocation,result;

cout<<"移除前:";

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

result=remove_if(v.begin(),v.end(),even);

cout<<"移除后:";

for(ilocation=v.begin();ilocation!=result;ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

}


8 剔除连续重复元素unique

函数原型:unique(v.begin(),v.end());

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v;

v.push_back(2);

v.push_back(6);

v.push_back(6);

v.push_back(6);

v.push_back(9);

v.push_back(6);

v.push_back(3);

vector<int>::iterator ilocation,result;

result=unique(v.begin(),v.end());

for(ilocation=v.begin();ilocation!=result;ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

}


输出结果:2 6 9 6 3

三、排序算法

1、创建堆make_heap

2、元素入堆push_heap(默认插入最后一个元素)

3、元素出堆pop_heap(与push_heap一样,pop_heap必须对堆操作才有意义)

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v;

v.push_back(5);

v.push_back(6);

v.push_back(4);

v.push_back(8);

v.push_back(2);

v.push_back(3);

v.push_back(7);

v.push_back(1);

v.push_back(9);

make_heap(v.begin(),v.end());

v.push_back(20);

push_heap(v.begin(),v.end());

vector<int>::iterator ilocation;

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

pop_heap(v.begin(),v.end());

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

}


4 堆排序sort_heap

使用:

复制代码 代码如下:

make_heap(v.begin(),v.end());

sort_heap(v.begin(),v.end());

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v;

v.push_back(3);

v.push_back(9);

v.push_back(6);

v.push_back(3);

v.push_back(17);

v.push_back(20);

v.push_back(12);

vector<int>::iterator ilocation;

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

make_heap(v.begin(),v.end());

sort_heap(v.begin(),v.end());

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

}


输出结果:

3 9 6 3 17 20 12
3 3 6 9 12 17 20

5 排序sort

函数原型:sort(v.begin(),v.end());

复制代码 代码如下:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

void main()

{

vector<int> v;

v.push_back(2);

v.push_back(8);

v.push_back(-15);

v.push_back(90);

v.push_back(26);

v.push_back(7);

v.push_back(23);

v.push_back(30);

v.push_back(-27);

v.push_back(39);

v.push_back(55);

vector<int>::iterator ilocation;

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

sort(v.begin(),v.end());//比较函数默认

for(ilocation=v.begin();ilocation!=v.end();ilocation++)

cout<<*ilocation<<' ';

cout<<endl;

}

相关文章

  • C语言实现文件内容的加密与解密

    C语言实现文件内容的加密与解密

    文件内容需要加密与解密功能的原因主要有两个方面:保护数据安全和确保数据完整性,所以接下来小编就给大家介绍一下如何通过C语言实现文件内容加密与解密,需要的朋友可以参考下
    2023-08-08
  • C/C++ Qt TabWidget 实现多窗体创建详解

    C/C++ Qt TabWidget 实现多窗体创建详解

    TabWidget组件配合自定义Dialog组件,可实现一个复杂的多窗体分页结构。这篇文章就主要介绍了如何通过TabWidget实现多窗体的创建,感兴趣的小伙伴可以了解一下
    2021-12-12
  • C语言实现扫雷小程序

    C语言实现扫雷小程序

    这篇文章主要为大家详细介绍了C语言实现扫雷小程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • C++实现百度坐标(BD09)及GCJ02与WGS84之间的转换

    C++实现百度坐标(BD09)及GCJ02与WGS84之间的转换

    这篇文章主要为大家详细介绍了C++实现百度坐标(BD09)及GCJ02与WGS84之间的转换的方法,文中的示例代码讲解详细,希望对大家有所帮助
    2023-03-03
  • C语言数据结构与算法之队列的实现详解

    C语言数据结构与算法之队列的实现详解

    队列只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的原则。本文将通过实例详细说说队列的实现,需要的可以学习一下
    2022-10-10
  • C++中的四种类型转换

    C++中的四种类型转换

    类型转换有c风格的,当然还有c++风格的。c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,
    2015-08-08
  • C语言堆栈帧的介绍与创建

    C语言堆栈帧的介绍与创建

    这篇文章主要给大家介绍了关于C语言堆栈帧的相关资料,堆栈帧 (stack frame)( 或活动记录 (activation Tecord)) 是一块堆栈保留区域,用于存放被传递的实际参数、子程序的返回值、局部变量以及被保存的寄存器,需要的朋友可以参考下
    2021-08-08
  • C语言动态内存分配图文讲解

    C语言动态内存分配图文讲解

    给数组分配多大的空间?你是否和初学C时的我一样,有过这样的疑问。这一期就来聊一聊动态内存的分配,读完这篇文章,你可能对内存的分配有一个更好的理解
    2023-01-01
  • return和break的区别解析

    return和break的区别解析

    这篇文章主要介绍了return和break的区别解析,需要的朋友可以参考下
    2014-02-02
  • C++ COM编程之什么是接口?

    C++ COM编程之什么是接口?

    这篇文章主要介绍了C++ COM编程之什么是接口?在C++中,可以使用抽象基类来实现COM接口,需要的朋友可以参考下
    2014-10-10

最新评论