c++STL之常用的算法

目录

常用的遍历算法

for_each()

transform()

for_each()和transform()算法比较 

常用的查找算法

adjacent_find()

binary_search

count()  

count_if()  

find()

常用的排序算法 

merge()

sort()

random_shuffle()

reverse()  

常用的拷贝算法和替换算法 

copy()

replace()和replace_if()

swap()

​编辑常用的算数和生成算法 

accumulate()

fill()


常用的遍历算法

for_each()

  • for_each:  用指定函数依次对指定范围内所有元素进行迭代访问。该函数不得修改序列中的元素。
class CMyShow
{
public:
	CMyShow()
	{
		num = 0;
	}
	void operator()(int &n)
	{
		num++;
		cout << n << " ";
	}
	void printNum()
	{
		cout << "num:" << num << endl;
	}
private:
	int num;
};
void main31_foreach()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);

	printV(v1);
	cout << endl;

	//函数对象 回调函数入口地址
	for_each(v1.begin(), v1.end(), Showvector);
	cout << endl;
	
	for_each(v1.begin(), v1.end(), CMyShow());
	cout << endl;

	CMyShow mya;
	CMyShow my1 = for_each(v1.begin(), v1.end(), mya);
	my1.printNum();//mya和my1是两个不同的对象
	mya.printNum();
	cout << endl;

	my1 = for_each(v1.begin(), v1.end(), mya);
	my1.printNum();//mya和my1是两个不同的对象
	mya.printNum();
	cout << endl;
}

这边需要注意的是for_each函数的返回值和第三个形参是两个不同的对象

 

我们可以看到源码的第三个参数是值传递方式,所以与实参不是同一个对象。

transform()

  • transform:   与for_each类似,遍历所有元素,但可对容器的元素进行修改
  • transform()算法有两种形式: 
    • transform(b1, e1, b2, op) 
    • transform(b1, e1, b2, b3, op)
  • transform()的作用

例如:可以一个容器的元素,通过op,变换到另一个容器中(同一个容器中)

也可以把两个容器的元素,通过op,变换到另一个容器中

 

 

 

  • 注意: 1.如果目标与源相同,transform()就和for_each()一样

                   2.如果想以某值替换符合规则的元素,应使用replace()算法

void main32_transform()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);

	printV(v1);
	cout << endl;
	
	//使用回调函数
	transform(v1.begin(), v1.end(), v1.begin(), increase);
	printV(v1);
	cout << endl;

	//使用预定义的函数对象
	transform(v1.begin(), v1.end(), v1.begin(), negate<int>());
	printV(v1);
	cout << endl;

	//使用函数适配器和函数对象
	list<int> mylist;
	mylist.resize(v1.size());
	transform(v1.begin(), v1.end(), mylist.begin(), bind2nd(multiplies<int>(), 10));
	printList(mylist);
	cout << endl;

	//transform也可以把运算结果直接输出到屏幕
	transform(v1.begin(), v1.end(), ostream_iterator<int>(cout, " "), negate<int>());
	cout << endl;
}

for_each()和transform()算法比较 

void showElem(int& n)
{
	cout << n << " ";
}
int showElem2(int n)
{
	cout << n << " ";
	return n;
}

void main43_transform_pk_foreach()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);

	vector<int> v2 = v1;
	for_each(v1.begin(), v1.end(), showElem);
	cout << endl;

	transform(v2.begin(), v2.end(), v2.begin(), showElem2);
}

一般情况下:for_each所使用的函数对象,参数是引用,没有返回值 

transform所使用的函数对象,参数一般不使用引用,而是还有返回值

常用的查找算法

adjacent_find()

在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的迭代器。否则返回past-the-end。

void main44_adjacent_find()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(5);

	vector<int>::iterator it = adjacent_find(v1.begin(), v1.end());
	if (it == v1.end())
	{
		cout << "没有找到重复的元素" << endl;
	}
	else
	{
		cout << *it << endl;
	}
	int index = distance(v1.begin(), it);
	cout << index << endl;
}

在有序序列中查找value,找到则返回true,即二分查找的方式。注意:在无序序列中,不可使用。

//二分法查找数据 1k=1024 10次
void main45_binary_search()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	v1.push_back(7);
	v1.push_back(9);

	bool b = binary_search(v1.begin(), v1.end(), 7);
	if (b == true)
	{
		cout << "找到了" << endl;
	}
	else
	{
		cout << "没找到" << endl;
	}
}

count()  

利用等于操作符,把标志范围内的元素与输入值比较,返回相等的个数。

void main46_count()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	v1.push_back(7);
	v1.push_back(7);
	v1.push_back(7);
	v1.push_back(9);

	int num = count(v1.begin(), v1.end(), 7);
	cout << num << endl;
}

 

count_if()  

 

bool GeatThree(int iNum)
{
	if (iNum > 3)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void main47_countif()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	v1.push_back(7);
	v1.push_back(7);
	v1.push_back(7);
	v1.push_back(9);

	int num = count_if(v1.begin(), v1.end(), GeatThree);
	cout << num << endl;
}

find()

  • find:  利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的迭代器。
void main48_find()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(7);
	v1.push_back(5);
	v1.push_back(7);
	v1.push_back(7);
	v1.push_back(9);

	vector<int>::iterator it = find(v1.begin(), v1.end(), 5);
	cout << "*it:" << *it << endl;

	vector<int>::iterator it2 = find_if(v1.begin(), v1.end(), GeatThree);
	cout << "*it2:" << *it2 << endl;
}

 

常用的排序算法 

merge()

  • 以下是排序和通用算法:提供元素排序策略
  • merge:    合并两个有序序列,存放到另一个序列。

例如:vecIntA,vecIntB,vecIntC是用vector<int>声明的容器,vecIntA已包含1,3,5,7,9元素,vecIntB已包含2,4,6,8元素

vecIntC.resize(9);  //扩大容量

merge(vecIntA.begin(),vecIntA.end(),vecIntB.begin(),vecIntB.end(),vecIntC.begin());

此时vecIntC就存放了按顺序的1,2,3,4,5,6,7,8,9九个元素

void main_merge()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);

	vector<int> v2;
	v2.push_back(2);
	v2.push_back(4);
	v2.push_back(6);

	vector<int> v3;
	v3.resize(v1.size() + v2.size());

	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
	
	printV(v3);
}

注意:这边的两个容器必须是有序的,否则程序会dump。

sort()

  • sort:  以默认升序的方式重新排列指定范围内的元素。若要改排序规则,可以输入比较函数。
class Student
{
public:
	Student(string name, int id)
	{
		m_name = name;
		m_id = id;
	}
	void prinT()
	{
		cout << "name:" << m_name << "id:" << m_id << endl;
	}
	string m_name;
	int m_id;
};

bool CompareS(Student& s1, Student& s2)
{
	return (s1.m_id < s2.m_id);
}

void main_sort()
{
	Student s1("老大", 1);
	Student s2("老二", 2);
	Student s3("老三", 3);
	Student s4("老四", 4);
	vector<Student> v1;
	v1.push_back(s4);
	v1.push_back(s1);
	v1.push_back(s3);
	v1.push_back(s2);

	for (vector<Student>::iterator it = v1.begin(); it != v1.end(); it++)
	{
		it->prinT();
	}
	sort(v1.begin(), v1.end(), CompareS);
	cout << "排序之后" << endl;
	for (vector<Student>::iterator it = v1.begin(); it != v1.end(); it++)
	{
		it->prinT();
	}
}

 

random_shuffle()

  • random_shuffle:     对指定范围内的元素随机调整次序。

srand(time(0)); //设置随机种子

void main_random_shuffle()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	v1.push_back(7);

	random_shuffle(v1.begin(), v1.end());
	printV(v1);

	string str = "abcdefg";
	random_shuffle(str.begin(), str.end());
	cout << "str:" << str << endl;
}

reverse()  

翻转容器的元素或者字符串的元素

void main_reverse()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	v1.push_back(7);

	reverse(v1.begin(), v1.end());
	printV(v1);
}

常用的拷贝算法和替换算法 

copy()

void main_copy()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	v1.push_back(7);

	vector<int> v2;
	v2.resize(v1.size());

	copy(v1.begin(), v1.end(), v2.begin());
	printV(v2);
}

replace()和replace_if()

  • replace(beg,end,oldValue,newValue):    将指定范围内的所有等于oldValue的元素替换成newValue。
bool great_equal_5(int& n)
{
	if (n >= 5)
	{
		return true;
	}
	return false;
}

void main_replace_replaceif()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	v1.push_back(7);
	v1.push_back(3);

	replace(v1.begin(), v1.end(), 3, 8);
	printV(v1);
	cout << endl;

	//>=5
	replace_if(v1.begin(), v1.end(), great_equal_5, 8);
	printV(v1);
}

swap()

  • swap:   交换两个容器的元素
void main_swap()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);

	vector<int> v2;
	v2.push_back(2);
	v2.push_back(4);
	v2.push_back(6);

	swap(v1, v2);
	printV(v1);
}

常用的算数和生成算法 

accumulate()

  • accumulate:  对指定范围内的元素求和,然后结果再加上一个由val指定的初始值。
  • #include<numeric>
void main_accumulate()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);

	int tmp = accumulate(v1.begin(), v1.end(), 100);
	cout << tmp << endl;
}

fill()

fill:   将输入值赋给标志范围内的所有元素

void main_fill()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);

	fill(v1.begin(), v1.end(), 8);
	printV(v1);
}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值