C++ 常用算法

一、引言

        ※本文记录一些C++常用的算法,用于简单使用

  •      一般要使用C++的内置算法,需要包含以下三个头文件:

                #include<algorithm>#include<functional>#include<numeric>

头文件解释
#include<algorithm>

        algorithm是STL头文件中最大的一个,

涉及:比较交换查找遍历修改复制等操作。

#include<functional>定义了一些函数模板,用于仿函数
#include<numeric>体积很小,仅仅包括几个在序列上进行简单数学运算函数模板

二、常用遍历算法

2.1 for_each

        for_each会遍历整个容器,它的使用方法如下所示:

声明解释
for_each(iterator begin, iterator end, 仿函数函数);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
  • 第三个参数指的是仿函数或者函数的名称,这个函数或者仿函数的参数应该是一个容器的元素类型,为每一个元素执行这个函数仿函数的行为。

        下面用一个小示例来具体说明如何使用for_each函数:

//函数
void printInt(int elem) {
	cout << elem << " ";
}

//仿函数
class PrintInt {
public:
	void operator()(int elem) const {
		cout << elem << " ";
	}
};

//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}//v0 = 0 1 2 3 4

	//第三个参数为仿函数
	PrintInt print_int;
	cout << "第三个参数是仿函数:" << endl;
	for_each(v0.begin(), v0.end(), print_int);
	cout << endl;

	//第三个参数为函数
	cout << "第三个参数是函数:" << endl;
	for_each(v0.begin(), v0.end(), printInt);
	cout << endl;

	return 0;

}

        程序的执行结果如下所示:

2.2 transform

        transform会将一个容器的全部元素复制到另一个容器中,它的函数声明如下所示:

注意:在使用之前,一定要先让目标容器使用resize(源容器.size())先设置其容量!!

声明解释

                    transform(iterator begin1,

              iterator end1,

                                      iterator begin2,

                                      仿函数函数);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为源容器迭代器复制区间,也就是会将对begin开始到end的元素进行复制。
  • 第三个参数是目标容器开始迭代器,也就是将元素们begin2开始复制
  • 第四个参数指的是仿函数或者函数的名称,它的作用是:在复制到目标容器前,可以对元素进行某种计算或者处理,之后再将处理后的值填入目标容器。(当前,也可以什么都不做)

         下面用一个小示例来具体说明如何使用transform函数:

//输出函数
void printInt(int elem) {
	cout << elem << " ";
}

//函数:值+1
int  changeInt(int elem) {
	elem++;

	return elem;
}

//仿函数:值-1
class ChangeInt {
public:
	int operator()(int i) {
		i--;

		return i;
	}
};

int main() {
	vector<int> v0;//源容器
	vector<int> v1;//目标容器:第四个参数使用函数
	vector<int> v2;//目标容器:第四个参数使用仿函数
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}//v0 = 0 1 2 3 4

	//输出v0
	cout << "v0 : [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;
	//输出v1
	cout << "v1 : [";
	for_each(v1.begin(), v1.end(), printInt);
	cout << "]" << endl;
	//输出v2
	cout << "v2 : [";
	for_each(v2.begin(), v2.end(), printInt);
	cout << "]" << endl;

	//使用transform函数:第四个参数使用函数
	v1.resize(v0.size());
	transform(v0.begin(), v0.end(), v1.begin(), changeInt);

	//使用transform函数:第四个参数使用仿函数
	v2.resize(v0.size());
	ChangeInt change;
	transform(v0.begin(), v0.end(), v2.begin(), change);

	//输出v0
	cout << "v0 : [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;
	//输出v1
	cout << "v1 : [";
	for_each(v1.begin(), v1.end(), printInt);
	cout << "]" << endl;
	//输出v2
	cout << "v2 : [";
	for_each(v2.begin(), v2.end(), printInt);
	cout << "]" << endl;

    return 0;
}

        以上例子,将第四个参数设置为函数,将v0的每个值+1后,搬运给v1

                        将第四个参数设置为仿函数,将v0的每个值-1后,搬运给v2,程序执行结果如下:

三、常用查找算法

3.0 注意

        针对自定义类型的查找算法:在比较过程中,其实程序并不知道如何比较两个元素是否相等,也就是没有对应的==运算符。因此,我们需要在自定义类中重载==运算符

                     (下文中只在findfind_if中做示例说明,此外的其余函数均同理)

       ※  binary_search只能用于有序序列

3.1 find

        find用于查找容器中的指定元素。

如果找到,则返回元素的迭代器;如果没找到,则返回本容器的结束迭代器end()。声明如下:

声明解释
find(iterator begin, iterator end, value);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
  • 第三个参数为想要查找元素的值

3.1.1 内置类型元素的find

vector<int> v0;
for (int i = 0; i < 10; i++) {
	v0.push_back(i);
}//v0 = 0 1 2 3 4 5 6 7 8 9

vector<int>::iterator it4 = find(v0.begin(), v0.end(), 4);
cout << "find 4 : " << boolalpha << (*it4 == 4) << endl;

vector<int>::iterator it11 = find(v0.begin(), v0.end(), 11);
cout << "find 11 : " << boolalpha << (*it4 == 11) << endl;

        程序的执行结果如下所示:

3.1.2 自定义类型元素的find

        当我们需要查找的是自定义类型的元素时,在比较过程中,其实程序并不知道如何比较两个元素是否相等,也就是没有对应的==运算符。因此,我们需要在自定义类中重载==运算符

//Person类
class Person {
	public:
		string name;
		int age;

		Person(string n, int a) : name(n), age(a){}

		//重载==运算符
		bool operator==(const Person &p) {
			
			return (this->name == p.name) && (this->age == p.age);
		}
};

//主函数
int main() {
	vector<Person> vp;

	Person p1("A", 18);
	vp.push_back(p1);
	Person p2("B", 18);
	vp.push_back(p2);
	Person p3("C", 18);
	vp.push_back(p3);
	Person p4("D", 18);
	vp.push_back(p4);
	Person p5("E", 18);
	vp.push_back(p5);

	//能找到的C
	Person p_find("C", 18);
	vector<Person>::iterator itp = find(vp.begin(), vp.end(), p_find);

	if (itp == vp.end()) {
		cout << "Not Find C!" << endl;
	} else {
		cout << "Find C !" << endl;
	}

	//找不到的W
	Person p_nfind("W", 18);
	itp = find(vp.begin(), vp.end(), p_nfind);

	if (itp == vp.end()) {
		cout << "Not Find W!" << endl;
	}
	else {
		cout << "Find W !" << endl;
	}

	return 0;
}

         程序的执行结果如下所示:

3.2 find_if

        find_if用于查找容器中的指定条件的元素。

如果找到,则返回元素的迭代器;如果没找到,则返回本容器的结束迭代器end()。声明如下:

声明解释
find_if(iterator begin, iterator end, _P);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
  • 第三个参数_P查找元素的条件_P可以是函数,也可以是谓词。

             (谓词就是返回值为bool仿函数)

 3.2.1 内置类型元素的find

//函数 : 数字 > 1
bool greaterOne(const int &num) {
	return (num > 1);
}

//仿函数: 数字 > 2
class GreaterTwo {
	public:
		bool operator()(const int& num) {
			return (num > 2);
		}
};

//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}// v0 = 0 1 2 3 4

    //第三个参数使用函数
	vector<int>::iterator it1 = find_if(v0.begin(), v0.end(), greaterOne);
	cout << "find greater than one num is (2): " << *it1 << endl;

    //第三个参数使用谓词
	GreaterTwo greaterTwo;
	vector<int>::iterator it2 = find_if(v0.begin(), v0.end(), greaterTwo);
	cout << "find greater than one num is (3): " << *it2 << endl;

    return 0;
}

         程序的执行结果如下所示:

3.2.2 内置类型元素的find_if

        这里与find相似,也需要重载==运算符

//Person类
class Person {
	public:
		string name;
		int age;

		Person(string n, int a) : name(n), age(a){}

		//重载==运算符
		bool operator==(const Person &p) {
			
			return (this->name == p.name) && (this->age == p.age);
		}
};

//函数 : 名字为A 
bool isA(const Person &per) {
	return (per.name == "A");
}

//仿函数: 名字为C
class IsC {
	public:
		bool operator()(const Person &per) {
			return (per.name == "C");
		}
};

//主函数
int main() {
	vector<Person> vp;

	Person p1("A", 10);
	vp.push_back(p1);
	Person p2("B", 20);
	vp.push_back(p2);
	Person p3("C", 30);
	vp.push_back(p3);
	Person p4("D", 40);
	vp.push_back(p4);
	Person p5("E", 50);
	vp.push_back(p5);

	//第三个参数为函数
	vector<Person>::iterator ita = find_if(vp.begin(), vp.end(), isA);
	cout << "find A's age is (10): " << ita->age << endl;

	//第三个参数为谓词
	IsC isC;
	vector<Person>::iterator itc = find_if(vp.begin(), vp.end(), isC);
	cout << "find C's age is (30): " << itc->age << endl;

         程序运行的结果如下所示:

3.3 adjacent_find

        adjacnet_find用于查找容器中的相邻重复的元素。

如果找到,则返回第一个元素的迭代器;如果没找到,则返回本容器的结束迭代器end()。声明如下:

声明解释
adjacent_find(iterator begin, iterator end);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
int main() {
	vector<int> v0;
	for (int i = 1; i < 4; i++) {
		for (int j = 0; j < i; j++) {
			v0.push_back(i);
		}
	}// v0 = 1 2 2 3 3 3  

	vector<int>::iterator it = adjacent_find(v0.begin(), v0.end());
	cout << "*it (2): " << *it << endl;

	return 0;
}

         程序执行结果如下所示:

3.4 binary_search

        ※注意※:虽然查找速度快,在无序序列中不可以使用!!!!

        binary_search二分法查找容器中的指定条件的元素。

如果找到,则返回true;如果没找到,则返回false。声明如下:

声明解释
binary_search(iterator begin, iterator end, value);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
  • 第三个参数value为想要查找的元素
vector<int> v0;
for (int i = 0; i < 10; i++) {
	v0.push_back(i);	
}// v0 = 0 1 2 3 4 5 6 7 8 9    

bool exist_4 = binary_search(v0.begin(), v0.end(), 4);
cout << "Is 4 exist : " << boolalpha << exist_4 << endl;

bool exist_10 = binary_search(v0.begin(), v0.end(), 10);
cout << "Is 10 exist : " << boolalpha << exist_10 << endl;

         程序的执行结果如下所示:

3.5 count

        count用于统计容器中指定元素的个数,并返回。声明如下:

声明解释
count(iterator begin, iterator end, value);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
  • 第三个参数为想要统计个数的元素的值
vector<int> v0;
for (int i = 0; i < 5; i++) {
	for (int j = 0; j < i; j++) {
		v0.push_back(i);
	}
}// v0 = 1 2 2 3 3 3 4 4 4 4

int count_3 = count(v0.begin(), v0.end(), 3);
cout << "3's count is (3): " << count_3 << endl;

int count_5 = count(v0.begin(), v0.end(), 5);
cout << "5's count is (0): " << count_5 << endl;

         程序的执行结果如下所示:

3.6 count_if

        count_if用于指定某种条件,然后统计容器中符合条件元素的个数,并返回。声明如下:

声明解释
count(iterator begin, iterator end, _P);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
  • 第三个参数_P函数谓词,用于指定条件
//函数 > 3
bool greaterThree(const int& num) {
	return (num > 3);
}

//仿函数 < 3
class LessThree {
	public:
		bool operator()(const int & num) {
			return (num < 3);
		}
};

//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < i; j++) {
			v0.push_back(i);
		}
	}// v0 = 1 2 2 3 3 3 4 4 4 4

	int greater_3 = count_if(v0.begin(), v0.end(), greaterThree);//4 4 4 4 
	cout << "Num which greater than three is (4): " << greater_3 << endl;

	LessThree lessThree;
	int less_3 = count_if(v0.begin(), v0.end(), lessThree);//1 2 2 
	cout << "Num which less than three is (3): " << less_3 << endl;

	return 0;
}

         程序的执行结果如下所示:

 四、常用排序算法

4.1 sort

        sort用于对容器中的某段区间的元素进行排序(默认升序)。声明如下:

声明解释
sort(iterator begin, iterator end, _P);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
  • 第三个参数_P指定排序规则,下边示例中会展示。

4.1.1 默认升序排序

        sort默认排序为升序,示例如下:

//输出元素函数
void printInt(const int &num) {
	cout << num << " ";
}

//主函数
int main() {
	vector<int> v0;
	v0.push_back(10);
	v0.push_back(40);
	v0.push_back(20);
	v0.push_back(50);
	v0.push_back(30);

	//输出v0所有元素
	cout << "Before sort, v0 : [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	sort(v0.begin(), v0.end());

	//输出v0所有元素

	cout << "After sort, v0 : [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	return 0;
}

         程序执行结果如下所示:

4.1.2 指定排序规则(自定义类型)

        当我们希望元素降序排序,当容器元素的类型是我们自定义类型,其实这两种情况是类似的,都需要告知sort我们的排序规则。这边是上文提及的第三个参数_P

4.1.2.1 降序

        我们可以使用内置仿函数greater<T>,来实现容器元素的降序排序,也可以通过自己写的

仿函数函数告知规则。使用greater<T>时需包含头文件#include<functional>。示例如下:

//输出元素函数
void printInt(const int &num) {
	cout << num << " ";
}

//函数:自定义降序规则
bool myIntDown(const int &num1, const int& num2) {
	//排序规则其实就是:两个元素进行比较,把谁排在前边
	//降序规则:如果num1 > num2,则 “把num排在前边” = true
	return num1 > num2;
}

//仿函数:自定义降序规则
class MyDown {
	public:
		bool operator()(const int &num1, const int& num2) {
			return num1 > num2;
		}
};

//主函数
int main() {
	vector<int> v0;//通过内置仿函数greater<T>
	vector<int> v1;//通过自定义函数
	vector<int> v2;//通过自定义仿函数

	v0.push_back(10);
	v0.push_back(40);
	v0.push_back(20);
	v0.push_back(50);
	v0.push_back(30);

	v1.push_back(10);
	v1.push_back(40);
	v1.push_back(20);
	v1.push_back(50);
	v1.push_back(30);

	v2.push_back(10);
	v2.push_back(40);
	v2.push_back(20);
	v2.push_back(50);
	v2.push_back(30);

	//输出v0、v1和v2的所有元素
	cout << "Before sort, v0 : [";
    for_each(v0.begin(), v0.end(), printInt);
    cout << "]" << endl;

    cout << "Before sort, v1 : [";
    for_each(v1.begin(), v1.end(), printInt);
    cout << "]" << endl;

    cout << "Before sort, v2 : [";
    for_each(v2.begin(), v2.end(), printInt);
    cout << "]" << endl;

	//降序排序
	sort(v0.begin(), v0.end(), greater<int>());//通过内置仿函数greater<T>
	sort(v1.begin(), v1.end(), myIntDown);//通过自定义函数
	sort(v2.begin(), v2.end(), MyDown());//通过自定义仿函数

	//输出v0、v1和v2的所有元素
	cout << "After sort, v0 : [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	cout << "After sort, v1 : [";
	for_each(v1.begin(), v1.end(), printInt);
	cout << "]" << endl;

	cout << "After sort, v0 : [";
	for_each(v2.begin(), v2.end(), printInt);
	cout << "]" << endl;

	return 0;
}

         程序的执行结果如下所示:

4.1.2.2 自定义类型

        与上边类似,自定义类型就是需要告知sort自己的排序规则。这里再解释一下排序规则

无论是仿函数或函数,排序规则一般拥有两个参数firstsecond,返回值为bool类型。

在容器中,firstsecond前一个元素,而返回值就是代表当前顺序是否是对的

用前边的降序来说明:当first > second,此时就是降序,所以应该return true

                                     当first < second,此时不是降序,所以应该return false

下边再举一个小例子具体说明:

//自定义类型Thing
class Thing {
public :
	//排序规则,先按照one升序,在按照two升序
	int one;
	int two;

	Thing(int a, int b) : one(a), two(b) {}
};

//输出元素函数
void printThing(const Thing& thing) {
	cout << "(" << thing.one << ", " << thing.two << ")" << endl;
}

//函数:自定义排序规则
bool sortThing(const Thing& first, const Thing& second) {
	if (first.one < second.one) {
		//如果first的one < second的one,这种顺序是对的
		return true;
	}
	else if (first.one > second.one) {
		//如果first的one > second的one,这种顺序是错误的
		return false;
	}
	else {
		//当one相等,则比较two
		return first.two < second.two;
	}
}

//仿函数:自定义排序规则
class SortT {
	public:
		bool operator()(const Thing& first, const Thing& second) {
			if (first.one < second.one) {
				//如果first的one < second的one,这种顺序是对的
				return true;
			}
			else if (first.one > second.one) {
				//如果first的one > second的one,这种顺序是错误的
				return false;
			}
			else {
				//当one相等,则比较two
				return first.two < second.two;
			}
		}
};

//主函数
int main() {
	vector<Thing> v0;
	vector<Thing> v1;

	Thing t0(0, 2);
	v0.push_back(t0);
	v1.push_back(t0);
	Thing t1(1, 2);
	v0.push_back(t1);
	v1.push_back(t1);
	Thing t2(0, 1);
	v0.push_back(t2);
	v1.push_back(t2);
	Thing t3(2, 1);
	v0.push_back(t3);
	v1.push_back(t3);
	Thing t4(1, 1);
	v0.push_back(t4);
	v1.push_back(t4);
	Thing t5(3, 1);
	v0.push_back(t5);
	v1.push_back(t5);

	//打印v0和v1的全部元素
	cout << "Before sort :" << endl;
	cout << "---v0---" << endl;
	for_each(v0.begin(), v0.end(), printThing);
	cout << "--------" << endl;

	cout << "---v1---" << endl;
	for_each(v1.begin(), v1.end(), printThing);
	cout << "--------" << endl;

	//sort
	sort(v0.begin(), v0.end(), sortThing);//通过函数
	sort(v1.begin(), v1.end(), SortT());//通过仿函数

	//打印v0和v1的全部元素
	cout << "After sort :" << endl;
	cout << "---v0---" << endl;
	for_each(v0.begin(), v0.end(), printThing);
	cout << "--------" << endl;

	cout << "---v1---" << endl;
	for_each(v1.begin(), v1.end(), printThing);
	cout << "--------" << endl;

	return 0;
}

         程序的执行结果如下所示:

4.2 random_shuffle

       random_shuffle用于对容器中的某段区间的元素进行随机打乱排序。声明如下:

声明解释
random_shuffle(iterator begin, iterator end);

(使用前,记得包含头文 #include<algorithm>)

  • 第一个参数和第二个参数均为迭代器,指的是遍历的区间。
//输出元素函数
void printInt(const int& num) {
	cout << num << endl;
}

//主函数
int main() {
	vector<int> v0;

	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}//v0 = 0 1 2 3 4

	cout << "Before shuffle : " << endl;
	for_each(v0.begin(), v0.end(), printInt);

	random_shuffle(v0.begin(), v0.end());

	cout << "After shuffle : " << endl;
	for_each(v0.begin(), v0.end(), printInt);

	return 0;
}

        程序的执行结果如下所示:

4.3 merge

        ※注意※:使用merge之前,必须确保两个容器有序!!!

        merge可以将两个容器的元素进行合并。声明如下:

声明解释

merge(iterator begin1, iterator end1,

            iterator begin2, iterator end2,

            iterator target_iter);

(使用前,记得包含头文 #include<algorithm>)

  • 前四个参数分别代表被合并的容器的两个区间的起始区间
  • 第五个参数指的是合并后存储的目标容器的起始迭代器

        (※注意※  使用前请将目标容器resize

         再次强调一次,在使用merge前需要满足以下两个条件:

条件1被合并的两个容器元素必须有序
条件2目标容器必须提前设置足够大的容量

 

//输出int元素
void printInt(const int &elem) {
	cout << elem << " " << endl;
}

//主函数
int main() {
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	
	vector<int> v2;
	v2.push_back(4);
	v2.push_back(5);
	v2.push_back(6);

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

	merge(v1.begin(), v1.end() - 1, v2.begin(), v2.end() - 1, v3.begin());

	for_each(v3.begin(), v3.end(), printInt);

	return 0;
}

         程序的执行结果如下所示:

4.4 reverse

        reverse可以将容器中的指定区间元素反转。声明如下:

声明解释

reverse(iterator begin, iterator end);

(使用前,记得包含头文 #include<algorithm>)

  • 两个参数分别代表指定区间的起始迭代器
//输出int元素
void printInt(const int &elem) {
	cout << elem << " " << endl;
}

//主函数
int main() {
	vector<int> v1;
	for (int i = 0; i < 5; i++) {
		v1.push_back(i);
	}
	
	cout << "Before reverse :" << endl;
	for_each(v1.begin(), v1.end(), printInt);

	reverse(v1.begin() + 1, v1.end() - 1);

	cout << "After reverse :" << endl;
	for_each(v1.begin(), v1.end(), printInt);

	return 0;
}

程序的执行结果如下所示:

五、常用拷贝算法

                                            ※注意※  使用前请将目标容器resize)

        copy用于将容器中指定区间的元素拷贝到另一个容器中,声明如下:

声明解释

copy(iterator begin, iterator end, iterator des);

(使用前,记得包含头文 #include<algorithm>)

  • 前两个参数分别代表指定区间的起始迭代器
  • 第三个参数des代表目标容器的开始迭代器

        (※注意※  使用前请将目标容器resize

 

//输出int元素
void printInt(const int &elem) {
	cout << elem << " ";
}

//主函数
int main() {
	vector<int> v0;
	vector<int> v1;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}
	
	cout << "Before copy v1 :[";
	for_each(v1.begin(), v1.end(), printInt);
	cout << "]" << endl;

	v1.resize(v0.size());
	copy(v0.begin(), v0.end(), v1.begin());

	cout << "After copy v1 :[";
	for_each(v1.begin(), v1.end(), printInt);
	cout << "]" << endl;

	return 0;
}

         程序的结果如下所示:

六、常用替换算法

6.1 replace

        replace用于将容器中指定区间旧元素替换为新元素,声明如下:

声明解释

replace(iterator begin, iterator end,

                Elem oldValue, Elem newValue);

(使用前,记得包含头文 #include<algorithm>)

  • 前两个参数分别代表指定区间的起始迭代器
  • 第三个参数oldValue代表旧元素
  • 第四个参数newValue代表新元素
//输出int元素
void printInt(const int &elem) {
	cout << elem << " ";
}

//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
		v0.push_back(i);
		v0.push_back(i);
	}//v0 = 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4
	
	cout << "Before replace v0 :[";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	replace(v0.begin(), v0.end(), 2, 666);
	//v0 = 0 0 0 1 1 1 666 666 666 3 3 3 4 4 4

	cout << "After replace v0 :[";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	return 0;
}

         程序的直接结果如下所示:

6.2 replace_if

        replace_if用于将容器中指定区间符合指定条件的元素替换为新元素,声明如下:

声明解释

replace_if(iterator begin, iterator end,

                _P, Elem newValue);

(使用前,记得包含头文 #include<algorithm>)

  • 前两个参数分别代表指定区间的起始迭代器
  • 第三个参数_P表示指定条件,它可以使谓词函数
  • 第四个参数newValue代表新元素
//输出int元素
void printInt(const int &elem) {
	cout << elem << " ";
}

//函数:指定条件 0 < num < 3
bool _P(const int& num) {
	return (num > 0) && (num < 3);
}

//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
		v0.push_back(i);
		v0.push_back(i);
	}//v0 = 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4
	
	cout << "Before replace v0 :[";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	replace_if(v0.begin(), v0.end(), _P, 666);
	//v0 = 0 0 0 666 666 666 666 666 666 3 3 3 4 4 4

	cout << "After replace v0 :[";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	return 0;
}

         程序的执行结果如下所示:

6.3 swap

        swap用于互换两个容器,声明如下:

声明解释

swap(Container c1, Container c2);

(使用前,记得包含头文 #include<algorithm>)

  • 两个参数分别代表交换的两个容器
//输出int元素
void printInt(const int &elem) {
	cout << elem << " ";
}

//主函数
int main() {
	vector<int> v1;

	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}
	
	cout << "Before swap:" << endl;
	cout << "v0: [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;
	cout << "v1: [";
	for_each(v1.begin(), v1.end(), printInt);
	cout << "]" << endl;

	swap(v0, v1);

	cout << "After swap:" << endl;
	cout << "v0: [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;
	cout << "v1: [";
	for_each(v1.begin(), v1.end(), printInt);
	cout << "]" << endl;

	return 0;
}

        程序的执行结果如下所示:

七、常用的算术生成算法

                                    (使用前,记得包含头文 #include<numeric>)

7.1 accumulate

        accumulate用于统计容器中元素累计总和,声明如下:

声明解释

accumulate(iterator begin, iterator end, initV);

(使用前,记得包含头文 #include<numeric>)

  • 前两个参数分别代表指定区间的起始迭代器
  • 第三个参数initV表示:统计结果的初始值(如果initV为15,总和为10,则函数返回值为25)。
//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}//v0 = 0 1 2 3 4
	
	//15 + 0 + 1 + 2 + 3 + 4 = 25
	int sum = accumulate(v0.begin(), v0.end(), 15);

	cout << "sum : " << sum << endl;

	return 0;
}

         程序的执行结果如下所示:

7.2 fill

        fill用于将容器的指定区间元素全部替换为新元素,声明如下:

声明解释

fill(iterator begin, iterator end, newValue);

(使用前,记得包含头文 #include<numeric>)

  • 前两个参数分别代表指定区间的起始迭代器
  • 第三个参数newValue表示新值
//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}//v0 = 0 1 2 3 4
	
	cout << "Before fill :" << endl;
	cout << "v0: [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	fill(v0.begin() + 1, v0.end() - 1, 666);

	cout << "After fill :" << endl;
	cout << "v0: [";
	for_each(v0.begin(), v0.end(), printInt);
	cout << "]" << endl;

	return 0;
}

         程序执行的结果如下所示:

八、集合间元素的交集并集差集算法

                                   (※注意※  使用前请确保两个容器为有序序列

8.1 set_intersection

                                (※注意※  使用前请确保两个容器为有序序列

                             (※注意※  使用前请将目标容器resize二者容器的最小size

        set_intersection用于将两个集合容器的交集存储于目标容器,声明如下:

声明解释

set_intersection(iterator begin1, iterator end2,

                       iterator begin1, iterator end2,

                              iterator target_begin);

(使用前,记得包含 #include<algorithum>)

  • 前两个参数分别代表第一个集合起止迭代器
  • 后两个参数分别代表第二个集合起止迭代器
  • 最后一个参数target_begin表示存放交集开始迭代器

     (※注意※  使用前请将目标容器resize

//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}//v0 = 0 1 2 3 4

	vector<int> v1;
	for (int i = 2; i < 7; i++) {
		v1.push_back(i);
	}//v1 = 2 3 4 5 6
	
	vector<int> vTarget;
	vTarget.resize(min(v0.size(), v1.size()));//将vTarget进行resize
	set_intersection(v0.begin(), v0.end(), v1.begin(), v1.end(), vTarget.begin());

	for_each(vTarget.begin(), vTarget.end(), printInt);

	return 0;
}

         程序的执行结果如下所示:

8.2 set_union

                        (※注意※  使用前请将目标容器resize二者容器的size之和

                        (※注意※  使用前请确保两个容器为有序序列

        set_union用于将两个集合容器的并集存储于目标容器,声明如下:

声明解释

set_union(iterator begin1, iterator end2,

                       iterator begin1, iterator end2,

                              iterator target_begin);

(使用前,记得包含 #include<algorithum>)

  • 前两个参数分别代表第一个集合起止迭代器
  • 后两个参数分别代表第二个集合起止迭代器
  • 最后一个参数target_begin表示存放并集开始迭代器

     (※注意※  使用前请将目标容器resize

//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}//v0 = 0 1 2 3 4

	vector<int> v1;
	for (int i = 4; i < 10; i++) {
		v1.push_back(i);
	}//v1 = 4 5 6 7 8 9
	
	vector<int> vTarget;
	vTarget.resize(v0.size() + v1.size());//将vTarget进行resize
	set_union(v0.begin(), v0.end(), v1.begin(), v1.end(), vTarget.begin());

	for_each(vTarget.begin(), vTarget.end(), printInt);

	return 0;
}

         程序执行的结果如下所示:

                (并集中,只存在一个4,因为set集合中不存在重复元素。

                        如果使用multiset的话,则并集中会存在两个4,因为multiset允许重复元素存在)

8.3 set_difference

                        (※注意※  使用前请将目标容器resize二者容器的size之和

                        (※注意※  使用前请确保两个容器为有序序列

        set_difference用于将第一个容器对于第二个容器差集存储于目标容器,声明如下:

声明解释

set_difference(iterator begin1, iterator end2,

                       iterator begin1, iterator end2,

                              iterator target_begin);

(使用前,记得包含 #include<algorithum>)

  • 前两个参数分别代表第一个集合起止迭代器
  • 后两个参数分别代表第二个集合起止迭代器
  • 最后一个参数target_begin表示存放差集开始迭代器

     (※注意※  使用前请将目标容器resize

//输出int元素
void printInt(const int &elem) {
	cout << elem << " ";
}

//主函数
int main() {
	vector<int> v0;
	for (int i = 0; i < 5; i++) {
		v0.push_back(i);
	}//v0 = 0 1 2 3 4

	vector<int> v1;
	for (int i = 2; i < 7; i++) {
		v1.push_back(i);
	}//v1 = 2 3 4 5 6
	
	vector<int> vTarget;
	vTarget.resize(v0.size(), -1);//将vTarget进行resize
	set_difference(v0.begin(), v0.end(), v1.begin(), v1.end(), vTarget.begin());

	cout << "v0 对于 v1 的差集:" << endl;
	for_each(vTarget.begin(), vTarget.end(), printInt);
	cout << endl << "---------------------------" << endl;

	vTarget.resize(v1.size(), - 1);//将vTarget进行resize
	set_difference(v1.begin(), v1.end(), v0.begin(), v0.end(), vTarget.begin());

	cout << "v1 对于 v0 的差集:" << endl;
	for_each(vTarget.begin(), vTarget.end(), printInt);
	cout << endl << "---------------------------" << endl;

	return 0;
}

         程序的执行结果如下所示:

  • 25
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值