STL中的常用算法使用简介

1.for_each:遍历容器中的元素

void Print(int value)
{
    cout << value << " ";
}

class Print1
{
public:
    void operator()(int value)
    {
        cout << value << " ";
    }
};

int main(int argc, char *argv[])
{
    vector<int>v;
    for(int i = 0; i < 10; i++)
    {
        v.push_back(i);
    }
    //for_each函数的第三个参数有两种实现方法,一种是普通函数,一种是仿函数
    //在“stack,queue,list容器和随机访问”这篇文章最后有详细解释
    for_each(v.begin(), v.end(),Print);		//第一种
    cout << endl;
    for_each(v.begin(), v.end(),Print1());		//第二种
    cout << endl;
}

2.transform:搬运容器的内容到另一个容器中,可以在函数中做修改原容器的值

void Print(int value)
{
    cout << value << " ";
}

class Transform
{
public:
    int operator()(int v)
    {
        return v;
        //return v+100;		这样子就是将每个数据加上100以后再搬运
    }
};

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

    vector<int>v;
    vector<int>m;
    m.resize(v.size()+1);			//搬运的对象必须要提前开辟空间(QT中直接v.size()搬运失败?)
    for(int i = 0; i < 10; i++)
    {
        v.push_back(i);
    }
    for_each(v.begin(), v.end(), Print);
    cout << endl;

    transform(v.begin(),v.end(),m.begin(),Transform());
    for_each(v.begin(), v.end(), Print);		//两种形式,一种仿函数(类),一种普通函数
    cout << endl;

}

3.常用查找算法
函数原型

1.find:
find前两个参数为迭代器,最后一个为要查找的值,成功返回位置迭代器,失败返回第二个参数

查找内置数据类型时可以直接使用
   vector<int>::iterator it = find(v.begin(), v.end(),5);		//需要创建一个迭代器来接受返回值
   if(it == v.end())
   {
       cout << "not found" << endl;
   }
   else
   {
       cout << "found " << (*it) << endl;
   }

查找自定义数据类型的时候需要重载==
class Person
{
public:
    Person(string name, int age)
    {
        this->name = name;
        this->age = age;
    }
    bool operator==(const Person &p)			//在类中重载==才可以使用find函数
    {
        if(this->name == p.name && this->age == p.age)
            return true;
        else
            return false;
    }
    string name;
    int age;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    vector<Person>v;

    Person p1("aa",1);
    Person p2("bb",2);
    Person p3("cc",3);
    Person p4("dd",4);
    Person p5("ee",5);

    Person p6("cc",3);		//查找p6所代表的数据

    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    v.push_back(p5);

   vector<Person>::iterator it = find(v.begin(), v.end(),p6);
   if(it == v.end())
   {
       cout << "not found" << endl;
   }
   else
   {
       cout << "found: name = " << it->name << "\tage = "  << it->age << endl;
   }
    return a.exec();
}

2.find_if:
find前两个参数为迭代器,最后一个是伪函数或者函数,成功返回位置迭代器,失败返回第二个参数

查找内置数据类型:
bool fun(int value)
{
    return value>8;
}
void test2()
{
    vector<int>v;
    for(int i = 0; i < 10; i++)
    {
        v.push_back(i);
    }
    vector<int>::iterator it = find_if(v.begin(), v.end(), fun);		
    //这里同样可以同伪函数的形式来写,重载(),返回值类型为bool
    if(it == v.end())
    {
        cout << "not found" << endl;
    }
    else
    {
        cout << "found: " << *it << endl;
    }
查找自定义数据类型
class Person
{
public:
    Person(string name, int age)
    {
        this->name = name;
        this->age = age;
    }
    string name;
    int age;
};

bool fun1(Person &p)			//这里用函数实现的条件年龄大于2,也可以使用仿函数来实现
{
    return p.age>2;
}
void test1()
{
    vector<Person>v;

    Person p1("aa",1);
    Person p2("bb",2);
    Person p3("cc",3);
    Person p4("dd",4);
    Person p5("ee",5);

    Person p6("cc",3);

    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    v.push_back(p4);
    v.push_back(p5);

   vector<Person>::iterator it = find_if(v.begin(), v.end(),fun1);
   if(it == v.end())
   {
       cout << "not found" << endl;
   }
   else
   {
       cout << "found: name = " << it->name << "\tage = "  << it->age << endl;
   }
}

3.adjacent_find:
查找相邻的重复元素,两个参数,前后区间的迭代器,成功返回第一个元素的迭代器,失败返回后区间的迭代器
vector<int>::iterator it = adjacent_find(v.begin(), v.end());
//开发中使用的比较少,如果有两组重复元素只能返回第一组的迭代器
4.binary_search:
查找指定的元素是否存在,存在返回true,不存在返回false;
注意这个函数只能在有序序列中使用,否则结果不准确
bool ret = binary_search(v.begin(), v.end(), 9);
5.count:
统计元素个数,参数为前后区间和元素的值

统计内置数据类型:
int num = count(v.begin(), v.end(), 9);
统计自定义数据类型:
int num = count(v.begin(), v.end(), p);		//这里跟上面的find函数一样,需要在类中重载==

6.count_if与find_if形式基本相同,按条件统计元素个数

需要对比自定义数据类型的时候都要在类中重载==,因此底层的函数实现就是通过==号来识别数据的,但是自定义
的数据类型无法识别,因此需要重载,比如find和count都需要重载,但是find_if和count_if就不需要,因为它
没有通过==判断是否相等的操作,它需要判断的是大于小于,用不到==


上面的函数最后一个参数用函数或者仿函数都是可以的,形式上有点区别。
bool fun(int value)		//第一种形式参数要写fun
{
	return value>5;
}
class fun		//第二种形式调用的时候要写fun()
{
	bool operator()(int value)
	{
		return value>5;
	}
};

4.常用排序算法
函数原型

1.sort:
前两个参数为前后的迭代器,第三个参数是一个谓词,如果不填就按照从小到大的顺序进行排列
第三个参数可以用greater<int>(),变成从大到小的顺序进行排列。加上头文件#include <functional>
sort(v.begin(), v.end());		//从小到大
sort(v.begin(), v.end(),greater<int>());		//从大到小
2.random_shuffle:洗牌,打乱顺序
参数就是前后区间迭代器
加上头文件#include <ctime> 和语句 srand(unsigned int)time(NULL))让每次随机的结果都不一样
random_shuffle(v.begin(), v.end());
3.merge:
将两个有序容器中的元素合并放入另一个容器中,另一个容器依然是有序的
五个参数,两个容器的前后区间迭代器和另一个容器的前后区间迭代器
注意提前给目标容器分配空间vTarget.resize(v1.size()+v2.size());
merge(v1.gebin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
4.reserve:
两个参数前后区间迭代器
reserve(v.begin(), v.end());

5.常用拷贝和替换算法:
函数原型

1.copy:完全可以用=直接赋值,没啥意义
三个参数,拷贝对象的前后区间迭代器,和目的容器的开始迭代器
注意拷贝前要先将目的容器初始化
vTarget.resize(v.size());
vTareget.copy(v.begin(), v.end(), vTarget.begin());
2.replace:
四个参数,前后区间迭代器,旧值和新值,算法是替换区间内的所有值
replace(v.begin(), v.end(), 1, 2);
3.replace_if:
满足条件的替换,四个参数,前后区间迭代器,谓词和新值。
谓词可以用仿函数或者函数的形式来写
replace_if(v.begin(), v.end(), Greater3, 4);		//像这种大于3的条件,函数的返回值要写成Bool
bool Greater3(int value)
{
	return value>3;
}
4.swap:
交换两个同种容器中的元素
swap(v1,v2);

5.算术生成算法:

包含的头文件是#include <numeric>
1.accumulate:计算指定区间的值的总和
三个参数,前后区间迭代器和累加的起始值
int sum = accumulate(v.gebin(), v.end(), 0);
包含的头文件是#include <numeric>
2.fill:向指定区间填充值
fill(v.begin(), v.end(), 100);

6.常用集合算法
函数原型

1.set_intersection:求交集并放入另一个容器中,两个容器必须是一个有序序列
vTarget(min(v1.size(), v2.size());		//开辟空间的时候取两个容器中的较小值
vector<int>::iterator it = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
函数返回值是一个迭代器,指向最后一个有效数据,因为提前开辟的空间未必能够放满,所以遍历的时候不要用vTarget.end(),用这个函数返回的迭代器,否则出了交集外还有初始化时的默认值(0)。
2.set_union:求并集并放入另一个容器中,两个容器必须是一个有序序列
vTarget(v1.size()+v2.size());		//开辟空间的时候取两个容器的和
vector<int>::iterator it = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
函数返回值是一个迭代器,指向最后一个有效数据,因为提前开辟的空间未必能够放满,所以遍历的时候不要用vTarget.end(),用这个函数返回的迭代器,否则出了并集外还有初始化时的默认值(0)。
3.set_difference:求差集并放入另一个容器中,两个容器必须是一个有序序列
差集:v1和v2的差集就是v1中有的但是v2中没有的,顺序不同结果也是不同的
vTarget(max(v1.size(), v2.size());		//开辟空间的时候取两个容器中的较大值
vector<int>::iterator it = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
函数返回值是一个迭代器,指向最后一个有效数据,因为提前开辟的空间未必能够放满,所以遍历的时候不要用vTarget.end(),用这个函数返回的迭代器,否则出了交集外还有初始化时的默认值(0)。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值