c++STL常用算法之遍歷算法與查找算法——全面總結(附案例解析)(二十三)

這裏有C++STL——全面總結詳細教程(附案例解析)(持續更新中)


目錄

STL- 常用算法

常用遍歷算法

for_each

transform

常用查找算法

find

find_if

adjacent_find

binary_search

count

count_if


STL- 常用算法

概述:

  • 算法主要是由頭文件<algorithm> <functional> <numeric>組成。
  • <algorithm>是所有STL頭文件中最大的一個,範圍涉及到比較、 交換、查找、遍歷操作、複製、修改等等
  • <numeric>體積很小,只包括幾個在序列上面進行簡單數學運算的模板函數
  • <functional>定義了一些模板類,用以聲明函數對象。

 

常用遍歷算法

學習目標:

  • 掌握常用的遍歷算法

算法簡介:

  • for_each //遍歷容器

  • transform //搬運容器到另一個容器中

 

for_each

功能描述:

  • 實現遍歷容器

函數原型:

  • for_each(iterator beg, iterator end, _func);
  • // 遍歷算法 遍歷容器元素
  • // beg 開始迭代器
  • // end 結束迭代器
  • // _func 函數或者函數對象
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

void Print01(int val){
	cout << val << endl;
}

class Print02 {
public:
	void operator()(int val) {
		cout << val << " ";
	}
};

void test01() {
	vector<int>v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	for_each(v.begin(), v.end(), Print01);
	cout << endl;

	for_each(v.begin(), v.end(), Print02());
	cout << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

總結:for_each在實際開發中是最常用遍歷算法,需要熟練掌握

 

 

transform

功能描述:

  • 搬運容器到另一個容器中

函數原型:

  • transform(iterator beg1, iterator end1, iterator beg2, _func);
  • //beg1 源容器開始迭代器
  • //end1 源容器結束迭代器
  • //beg2 目標容器開始迭代器
  • //_func 函數或者函數對象
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class TransForm {
public:
	int operator()(int val){
		return val;
	}
};

class MyPrint {
public:
	void operator()(int val) {
		cout << val << " ";
	}
};

void test01() {
	vector<int>v;
	for (int i = 0; i < 10; i++){
		v.push_back(i);
	}

	vector<int>VTarget;
	VTarget.resize(v.size());

	transform(v.begin(), v.end(), VTarget.begin(), TransForm());

	for_each(VTarget.begin(), VTarget.end(), MyPrint());
	cout << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

總結: 搬運的目標容器必須要提前開闢空間,否則無法正常搬運.

 

 

常用查找算法

學習目標:

  • 掌握常用的查找算法

算法簡介:

  • find //查找元素
  • find_if //按條件查找元素
  • adjacent_find //查找相鄰重複元素
  • binary_search //二分查找法
  • count //統計元素個數
  • count_if //按條件統計元素個數

find

功能描述:

  • 查找指定元素,找到返回指定元素的迭代器,找不到返回結束迭代器end()

函數原型:

  • find(iterator beg, iterator end, value);
  • // 按值查找元素,找到返回指定位置迭代器,找不到返回結束迭代器位置
  • // beg 開始迭代器
  • // end 結束迭代器
  • // value 查找的元素
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

void test01() {
	vector<int>v;
	for (int i = 0; i < 10; i++){
		v.push_back(i);
	}

	vector<int>::iterator it = find(v.begin(), v.end(), 5);

	if (it == v.end()){
		cout << "沒有找到!" << endl;
	}
	else{
		cout << "找到:" << *it << endl;
	}
}

class Person {
public:
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}

	bool operator==(const Person&p) {
		if (this->m_Name == p.m_Name&&this->m_Age == p.m_Age) {
			return true;
		}
		else
			return false;
	}
public:
	string m_Name;
	int m_Age;
};

void test02() {
	vector<Person>v;
	Person p1("a", 10);
	Person p3("b", 20);
	Person p4("c", 30);

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

	vector<Person>::iterator pos;
	pos = find(v.begin(), v.end(), p3);
	if (pos == v.end()) {
		cout << "沒找到" << endl;
	}
	else {
		cout << "找到:" << pos->m_Name << "  " << pos->m_Age << endl;
	}
}

int main() {
	test01();
	test02();
	system("pause");
	return 0;
}

總結: 利用find可以在容器中找指定的元素,返回值是迭代器
 

 

find_if

功能描述:

  • 按條件查找元素

函數原型:

  • find_if(iterator beg, iterator end, _Pred);
  • // 按值查找元素,找到返回指定位置迭代器,找不到返回結束迭代器位置
  • // beg 開始迭代器
  • // end 結束迭代器
  • // _Pred 函數或者謂詞(返回bool類型的仿函數)

 

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

//內置數據類型
class GreaterFive{
public:
	bool operator()(int val){
		return val > 5;
	}
};

void test01() {
	vector<int>v;
	for (int i = 0; i < 10; i++){
		v.push_back(i);
	}

	vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());

	if (it == v.end()){
		cout << "沒有找到!" << endl;
	}
	else{
		cout << "找到:" << *it << endl;
	}
}

class Person {
public:
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}

public:
	string m_Name;
	int m_Age;
};

class Greater20 {
public:
	bool operator()(Person&p) {
		return p.m_Age >= 20;
	}
};

void test02() {
	vector<Person>v;
	Person p1("a", 10);
	Person p3("b", 20);
	Person p4("c", 30);

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

	vector<Person>::iterator pos;
	pos = find_if(v.begin(), v.end(),Greater20());
	if (pos == v.end()) {
		cout << "沒找到" << endl;
	}
	else {
		cout << "找到:" << pos->m_Name << "  " << pos->m_Age << endl;
	}
}

int main() {
	test01();
	test02();
	system("pause");
	return 0;
}

總結:find_if按條件查找使查找更加靈活,提供的仿函數可以改變不同的策略。

 

 

adjacent_find

功能描述:

  • 查找相鄰重複元素

函數原型:

  • adjacent_find(iterator beg, iterator end);
  • // 查找相鄰重複元素,返回相鄰元素的第一個位置的迭代器
  • // beg 開始迭代器
  • // end 結束迭代器

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

void test01() {
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(5);
	v.push_back(2);
	v.push_back(4);
	v.push_back(4);
	v.push_back(3);

	//查找相鄰重複元素
	vector<int>::iterator it = adjacent_find(v.begin(), v.end());
	if (it == v.end()) {
		cout << "找不到!" << endl;
	}
	else {
		cout << "找到相鄰重複元素爲:" << *it << endl;
	}
}

int main() {
	test01();

	system("pause");
	return 0;
}

總結:面試題中如果出現查找相鄰重複元素,記得用STL中的adjacent_find算法

 

功能描述:

  • 查找指定元素是否存在

函數原型:

  • bool binary_search(iterator beg, iterator end, value);
  • // 查找指定的元素,查到 返回true 否則false
  • // 注意: 在無序序列中不可用
  • // beg 開始迭代器
  • // end 結束迭代器
  • // value 查找的元素
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	bool ret = binary_search(v.begin(), v.end(), 2);
	cout << (ret ? "找到了" : "沒找到") << endl;
}

int main() {
	test01();

	system("pause");
	return 0;
}

總結:二分查找法查找效率很高,值得注意的是查找的容器中元素必須的有序序列

 

count

功能描述:

  • 統計元素個數

函數原型:

  • count(iterator beg, iterator end, value);
  • // 統計元素出現次數
  • // beg 開始迭代器
  • // end 結束迭代器
  • // value 統計的元素
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

//內置數據類型
void test01(){
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(4);
	v.push_back(5);
	v.push_back(3);
	v.push_back(4);
	v.push_back(4);
	int num = count(v.begin(), v.end(), 4);
	cout << "4的個數爲: " << num << endl;
}

//自定義數據類型
class Person{
public:
	Person(string name, int age){
		this->m_Name = name;
		this->m_Age = age;
	}
	bool operator==(const Person & p){
		if (this->m_Age == p.m_Age){
			return true;
		}
		else{
			return false;
		}
	}
	string m_Name;
	int m_Age;
};

void test02(){
	vector<Person> v;

	Person p1("劉備", 35);
	Person p2("關羽", 35);
	Person p3("張飛", 35);
	Person p4("趙雲", 30);
	Person p5("曹操", 25);

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

	Person p("諸葛亮", 35);

	int num = count(v.begin(), v.end(), p);
	cout << "num = " << num << endl;
}

int main() {
	test01();
	test02();

	system("pause");
	return 0;
}

總結: 統計自定義數據類型時候,需要配合重載 operator==

 

 

count_if

功能描述:

  • 按條件統計元素個數

函數原型:

  • count_if(iterator beg, iterator end, _Pred);
  • // 按條件統計元素出現次數
  • // beg 開始迭代器
  • // end 結束迭代器
  • // _Pred 謂詞
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

class Greater4 {
public:
	bool operator()(int val) {
		return val >= 4;
	}
};

//內置數據類型
void test01(){
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(4);
	v.push_back(5);
	v.push_back(3);
	v.push_back(4);
	v.push_back(4);
	int num = count_if(v.begin(), v.end(), Greater4());
	cout << "大於4的個數爲: " << num << endl;
}

//自定義數據類型
class Person{
public:
	Person(string name, int age){
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};
class AgeLess35{
public:
	bool operator()(const Person &p){
		return p.m_Age < 35;
	}
};

void test02(){
	vector<Person> v;

	Person p1("劉備", 35);
	Person p2("關羽", 35);
	Person p3("張飛", 35);
	Person p4("趙雲", 30);
	Person p5("曹操", 25);

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

	int num = count_if(v.begin(), v.end(), AgeLess35());
	cout << "num = " << num << endl;
}

int main() {
	test01();
	test02();

	system("pause");
	return 0;
}

總結:按值統計用count,按條件統計用count_if

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章