#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <functional>
#include <iterator> // istream_iterator,ostream_iterator,back_inserter
#include <iomanip> // 小数位控制
using namespace std;
void Algorithms();
#include "Algorithms.h"
/*------------------------------------------------------------------
* ①常用遍历算法
*-----------------------------------------------------------------*/
/*
for_each(iterator beg, iterator end, _callback);
遍历算法遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象
*/
// void CoutMap(map<int, string>::reference mp) //不要少了reference,不然会报错。
void CoutMap(map<int, string>::value_type& mp)
{
cout << mp.first << " " << mp.second << endl;
}
void For_EachDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
// map 遍历的三种方法
map<int, string> mp;
for (int i = 0; i < 10; i++) {
string temp = "string" + to_string(i);
mp.insert(make_pair(i, temp));
}
// 1 for 循环
cout << "for 循环实现: " << endl;
for (auto& value : mp) {
cout << value.first << " " << value.second << endl;
}
// 2 for_each + lambda 表达式
cout << "for_each + lambda 表达式实现: " << endl;
for_each(mp.begin(), mp.end(), [](map<int, string>::reference mp1) {cout << mp1.first << " " << mp1.second << endl; });
// 3 for_each + 自定义函数
cout << "for_each + 自定义函数Cout实现: " << endl;
for_each(mp.begin(), mp.end(), CoutMap);
}
/*
transform(iterator beg1, iterator end1, iterator beg2, _callbakc);
transform 算法将指定容器区间元素搬运到另一容器中
注意: transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器开始迭代器
@param end1 源容器结束迭代器
@param beg2 目标容器开始迭代器
@param _cakkback 回调函数或者函数对象
@return 返回目标容器迭代器
*/
void CoutVector(double d)
{
// fixed 表示小数位数不够时补0,setprecision 表示设置精度
cout << fixed << setprecision(2) << d << " ";
}
void TransformDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
vector<double> temperatureC{ 21.0, 30.5, 0.0, 3.2, 100.0 };
cout << "摄氏温度 :";
for_each(temperatureC.begin(), temperatureC.end(), CoutVector);
cout << endl;
vector<double> temperatureF(temperatureC.size());
transform(begin(temperatureC), end(temperatureC), begin(temperatureF),
[](double temp) { return 32.0 + 9.0 * temp / 5.0; });
cout << "华氏温度 :";
for_each(temperatureF.begin(), temperatureF.end(), CoutVector);
cout << endl;
vector<string> words{ "one", "two", "three", "four","five" };
cout << "单词: ";
copy(begin(words), end(words), ostream_iterator<string> {cout, " "});
cout << endl;
cout << "单词对应的hash值: ";
// vector<size_t> hash_values;
// transform(begin(words), end(words), back_inserter(hash_values), hash<string>()); // string hashing function
// copy(begin(hash_values), end(hash_values), ostream_iterator<size_t> {cout, " "});
hash<string> hash_values;
transform(begin(words), end(words), ostream_iterator<size_t>(cout, " "), hash_values); // string hashing function
cout << endl;
}
/*------------------------------------------------------------------
* ②常用查找算法
*-----------------------------------------------------------------*/
/*
find(iterator beg, iterator end, value);
find 算法查找元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找元素的位置
*/
void FindDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
// find() 函数作用于普通数组
// find()用于string
string string1 = "http://www.baidu.com";
string::iterator string_it = find(string1.begin(), string1.end(), 'c');
if (string_it != string1.end()) {
cout << "找到字符c在" << string1 << "中的位置为:" << string_it - string1.begin() << endl;
} else {
cout << "找到字符c在" << string1 << "中不存在" << endl;
}
// string 自带的find()
string string2 = "http://www.baidu.com";
int pos = string2.find('c', 0);
if (pos != string::npos) {
cout << "找到字符c在" << string2 << "中的位置为:" << pos << endl;
} else {
cout << "找到字符c在" << string2 << "中不存在" << endl;
}
//find() 函数作用于容器
vector<int> vec{ 10,20,30,40,50 };
vector<int>::iterator vec_it;
vec_it = find(vec.begin(), vec.end(), 30);
if (vec_it != vec.end()) {
cout << "查找到" << *vec_it << "在容器中," << "位置为:" << vec_it - vec.begin() << endl;
} else {
cout << "查找失败" << endl;
}
}
/*
find_if(iterator beg, iterator end, _callback);
find_if 算法条件查找
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回bool 类型的函数对象)
@return bool 查找返回true 否则false
*/
void Find_IfDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
vector<int> numbers = { 4,2,3,7,0,9,6 };
copy(numbers.begin(), numbers.end(), ostream_iterator<int> {cout, " "});
cout << endl;
int value{ 5 };
// auto iter1 = find_if(begin(numbers), end(numbers), [value](int num){return num > value;});
auto iter1 = find_if(begin(numbers), end(numbers), [value](int num)
{
return num > value;
}
);
if (iter1 != end(numbers)) {
cout << *iter1 << " was found greater than " << value << endl;
}
}
/*
adjacent_find(iterator beg, iterator end, _callback);
adjacent_find 算法查找相邻重复元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param _callback 回调函数或者谓词(返回bool 类型的函数对象)
@return 返回相邻元素的第一个位置的迭代器
*/
void Adjacent_FindDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
string saying{ "Children should be seen and noot heaard." };
auto string_it = adjacent_find(begin(saying), end(saying));
if (string_it != end(saying)) {
cout << "在字符串 \"" << saying << "\"中, '" << *string_it << "' 字符重复的位置在: " << distance(begin(saying), string_it) << endl;
}
cout << "找出所有重复字符:" << endl;
for (string::iterator it = begin(saying); it != end(saying); ) {
it = adjacent_find(it, end(saying));
if (it != end(saying)) {
cout << "在字符串 \"" << saying << "\"中, '" << *it << "' 字符重复的位置在: " << distance(begin(saying), it) << endl;
it++;
}
}
vector<long> numbers{ 64L, 46L, -65L, -128L, 121L, 17L, 35L, 9L, 91L, 5L };
auto vec_it = adjacent_find(begin(numbers), end(numbers), [](long num1, long num2) { return num1 % 2 && num2 % 2; });
if (vec_it != end(numbers)){
cout << "第一对相邻的奇数是: " << *vec_it << " and " << *(vec_it + 1) << endl;
}
}
/*
bool binary_search(iterator beg, iterator end, value);
binary_search 算法二分查找法
注意: 在无序序列中不可用
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return bool 查找返回true 否则false
*/
void Binary_SearchDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
vector<int> vec1 = { 1,2,3,4,5,6,7 };
copy(vec1.begin(), vec1.end(), ostream_iterator<int> {cout, " "});
cout << endl;
//从 a 数组中查找元素 4
bool elem1 = binary_search(vec1.begin(), vec1.begin() + 9, 4);
cout << "elem1: " << elem1 << endl;
vector<int> vec2{ 4,5,3,1,2 };
copy(vec2.begin(), vec2.end(), ostream_iterator<int> {cout, " "});
cout << endl;
//从 vec2 容器查找元素 3
bool elem2 = binary_search(vec2.begin(), vec2.end(), 3, [](int x, int y) { return x > y;});
cout << "elem2: " << elem2 << endl;
}
/*
count(iterator beg, iterator end, value);
count 算法统计元素出现次数
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 回调函数或者谓词(返回bool 类型的函数对象)
@return int 返回元素个数
*/
void CountDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
vector<int> vec1 = { 1,2,5,2,5,3,2,4,5,6,2,5,7,5 };
copy(vec1.begin(), vec1.end(), ostream_iterator<int> {cout, " "});
cout << endl;
int cnt2 = count(vec1.begin(), vec1.end(), 2);
int cnt5 = count(vec1.begin(), vec1.end(), 5);
cout << " the value 2 count = " << cnt2 << " the value 5 count = " << cnt5 << endl;
}
/*
count_if(iterator beg, iterator end, _callback);
count 算法统计元素出现次数
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回bool 类型的函数对象)
@return int 返回元素个数
*/
void Count_IfDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
vector<int> vec1 = { 1,2,5,2,5,3,2,4,5,6,2,5,7,5 };
copy(vec1.begin(), vec1.end(), ostream_iterator<int> {cout, " "});
cout << endl;
int cnt2 = count_if(vec1.begin(), vec1.end(), [](int x) { return ((x > 1) && (x < 3)); });
int cnt5 = count_if(vec1.begin(), vec1.end(), [](int x) { return ((x > 4) && (x < 6)); });
cout << " the value 2(count_if x > 1 && x < 3) count = " << cnt2 << " the value 5(count_if x > 4 && x < 6 count = " << cnt5 << endl;
}
/*------------------------------------------------------------------
* ③常用排序算法:如果要排序,则首先要对两个序列进行先排序
*-----------------------------------------------------------------*/
/*
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
merge 算法容器元素合并,并存储到另一容器中
@param beg1 容器1 开始迭代器
@param end1 容器1 结束迭代器
@param beg2 容器2 开始迭代器
@param end2 容器2 结束迭代器
@param dest 目标容器开始迭代器
*/
void MergeDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
// first 和 second 数组中各存有 1 个有序序列
vector<int> first = { 5,10,15,20,25 };
cout << "vec1 = ";
copy(first.begin(), first.end(), ostream_iterator<int> {cout, " "});
cout << endl;
vector<int> second = { 7,17,27,37,47,57 };
cout << "vec2 = ";
copy(second.begin(), second.end(), ostream_iterator<int> {cout, " "});
cout << endl;
// 用于存储新的有序序列
int size_merge = first.size() + second.size();
vector<int> merge_vec_default_sort(size_merge); // 这里定义时一定要开辟空间大小
// 将 [first.begin(),first.begin()+5) 和 [second.begin(),second.begin()+6) 合并为 1 个有序序列,并存储到 merge_vec 容器中。
merge(first.begin(), first.end(), second.begin(), second.end(), merge_vec_default_sort.begin());
// 输出 merge_vec 容器中存储的元素
cout << "merged vec default sort = ";
copy(merge_vec_default_sort.begin(), merge_vec_default_sort.end(), ostream_iterator<int> {cout, " "});
cout << endl;
// 自定义合并的排序方式
vector<int> merge_vec_custom_sort(size_merge); // 这里定义时一定要开辟空间大小
// 将 [first.begin(),first.begin()+5) 和 [second.begin(),second.begin()+6) 合并为 1 个有序序列,并存储到 merge_vec 容器中。
merge(first.begin(), first.end(), second.begin(), second.end(), merge_vec_custom_sort.begin(), greater<int>());
// 输出 merge_vec 容器中存储的元素
cout << "merged vec custom sort = ";
copy(merge_vec_custom_sort.begin(), merge_vec_custom_sort.end(), ostream_iterator<int> {cout, " "});
cout << endl;
}
/*
sort(iterator beg, iterator end, _callback);
sort 算法容器元素排序
注意:两个容器必须是有序的
@param beg 容器1 开始迭代器
@param end 容器1 结束迭代器
@param _callback 回调函数或者谓词(返回bool 类型的函数对象)
*/
void SortDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*
random_shuffle(iterator beg, iterator end);
sort 算法对指定范围内的元素随机调整次序
@param beg 容器开始迭代器
@param end 容器结束迭代器
*/
void Random_ShuffleDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*
reverse(iterator beg, iterator end);
reverse 算法反转指定范围的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
*/
void ReverseDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*------------------------------------------------------------------
* ④常用拷贝和替换算法
*-----------------------------------------------------------------*/
/*
copy(iterator beg, iterator end, iterator dest);
copy 算法将容器内指定范围的元素拷贝到另一容器中
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param dest 目标起始迭代器
*/
void CopyDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*
replace(iterator beg, iterator end, oldvalue, newvalue);
replace 算法将容器内指定范围的旧元素修改为新元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param oldvalue 旧元素
@param oldvalue 新元素
*/
void ReplaceDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*
replace_if(iterator beg, iterator end, _callback, newvalue);
replace_if 算法将容器内指定范围满足条件的元素替换为新元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 函数回调或者谓词(返回Bool 类型的函数对象)
@param oldvalue 新元素
*/
void Replace_IfDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*
swap(container c1, container c2);
swap 算法互换两个容器的元素
@param c1 容器1
@param c2 容器2
*/
void SwapDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*------------------------------------------------------------------
* ⑤常用算数生成算法
*-----------------------------------------------------------------*/
/*
accumulate(iterator beg, iterator end, value);
accumulate 算法计算容器元素累计总和
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 累加值
*/
void AccumulateDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*
fill(iterator beg, iterator end, value);
fill 算法向容器中添加元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t 填充元素
*/
void FillDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*------------------------------------------------------------------
* ⑥常用集合算法
*-----------------------------------------------------------------*/
/*
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
set_intersection 算法求两个set 集合的交集
注意:两个集合必须是有序序列
@param beg1 容器1 开始迭代器
@param end1 容器1 结束迭代器
@param beg2 容器2 开始迭代器
@param end2 容器2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
void Set_IntersectionDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
set_union 算法求两个set 集合的并集
注意:两个集合必须是有序序列
@param beg1 容器1 开始迭代器
@param end1 容器1 结束迭代器
@param beg2 容器2 开始迭代器
@param end2 容器2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
void Set_UnionDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
/*
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
set_difference 算法求两个set 集合的差集
注意:两个集合必须是有序序列
@param beg1 容器1 开始迭代器
@param end1 容器1 结束迭代器
@param beg2 容器2 开始迭代器
@param end2 容器2 结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
*/
void Set_DifferenceDemo()
{
cout << "--------" << __FUNCTION__ << "---------------------------------------------------------" << endl;
}
// 常用算法
void Algorithms()
{
For_EachDemo();
TransformDemo();
FindDemo();
Find_IfDemo();
Adjacent_FindDemo();
Binary_SearchDemo();
CountDemo();
Count_IfDemo();
MergeDemo();
}