算法小技巧集锦
- 1、打印
- 2、排序
- 3、删除特定元素
- 4、去重
- 5、std::all_of
- 6、std::none_of
- 7、std::any_of
- 8、std::minmax_element
- 9、std::copy_if
- 10、std::iota()
- 11、std::partition(),std::is_partitioned()
- 12、std::stable_partition(),std::partition_point()
- 13、std::partition_copy()
- 14、std::apply(),std::sum()
- 15、std::min(),std::max()
- 16、std::shift(),std::cshift()
1、打印
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void test_print()
{
std::cout << "打印" << std::endl;
std::vector<int> vec{1,2,3,4,6,8,4,0,20};
std::for_each(vec.begin(),vec.end(),[](auto& e){ std::cout << e << " ";});
std::cout << std::endl; // 1 2 3 4 6 8 4 0 20
std::copy(vecList.begin(), vecList.end(), std::ostream_iterator<int>(cout, ", "));
cout << endl; // 1 2 3 4 6 8 4 0 20
}
int main()
{
test_print();
return 0;
}
2、排序
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void test_print()
{
std::cout << "排序" << std::endl;
std::vector<int> vecList{1,2,3,4,6,8,4,0,20};
std::cout << "从小到大排序:" << std::endl;
std::sort(begin(vecList), end(vecList));
std::for_each(vecList.begin(), vecList.end(), [](auto& e) {cout << e << " "; });
cout << endl; // 0 1 2 3 4 4 6 8 20
std::cout << "从大到小排序:" << std::endl;
std::sort(begin(vecList), end(vecList), std::greater<int>());
std::for_each(vecList.begin(), vecList.end(), [](auto& e) {cout << e << " "; });
cout << endl; // 20 8 6 4 4 3 2 1 0
}
int main()
{
test_print();
return 0;
}
3、删除特定元素
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void test_print()
{
std::cout << "删除特定元素" << std::endl;
std::vector<int> vecList{1,2,3,4,6,8,4,0,20};
vecList.erase(std::remove(vecList.begin(), vecList.end(), 1), vecList.end());
std::for_each(vecList.begin(), vecList.end(), [](auto& e) {cout << e << " "; });
cout << endl; // 2 3 4 6 8 4 0 20
}
int main()
{
test_print();
return 0;
}
4、去重
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void test_print()
{
std::cout << "去重" << std::endl;
std::vector<int> vecList{1,2,3,4,6,8,4,0,20,1,4};
vecList.erase(std::unique(vecList.begin(), vecList.end()), vecList.end());
std::for_each(vecList.begin(), vecList.end(), [](auto& e) {cout << e << " "; });
cout << endl; // 1 2 3 4 6 8 0 20
}
int main()
{
test_print();
return 0;
}
5、std::all_of
- std::all_of:检查区间[first, last)中是否所有的元素都满足一元判断式p,所有的元素都满足条件返回true,否则返回false。
- std::all_of源码
// all_of 源码
template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 bool all_of(_InIt _First, _InIt _Last, _Pr _Pred) { // test if all elements satisfy _Pred
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
for (; _UFirst != _ULast; ++_UFirst) {
if (!_Pred(*_UFirst)) {
return false;
}
}
return true;
}
// 当传入容器为空,返回true
- 实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void test()
{
vector<int> v = { 1, 3, 5, 7, 9 };
auto isEven = [](int i) {return i % 2 != 0; };
bool isallOdd = std::all_of(v.begin(), v.end(), isEven); // 注意:当v为空时,返回true
if (isallOdd)
cout << "all is odd" << endl;
}
int main()
{
test();
return 0;
}
6、std::none_of
- std::none_of:检查区间[first, last)中是否所有的元素都不满足一元判断式p,所有的元素都不满足条件返回true,否则返回false。
- std::none_of源码
// none_of 源码
template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 bool none_of(const _InIt _First, const _InIt _Last, _Pr _Pred) {
// test if no elements satisfy _Pred
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
for (; _UFirst != _ULast; ++_UFirst) {
if (_Pred(*_UFirst)) {
return false;
}
}
return true;
}
// 当传入容器为空,返回true
- 实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void test()
{
vector<int> v = { 1, 3, 5, 7, 9 };
auto isEven = [](int i) {return i % 2 != 0; };
bool isNoneEven = std::none_of(v.begin(), v.end(), isEven); // 注意:当v为空时,返回true
if (isNoneEven)
cout << "none is even" << endl;
}
int main()
{
test();
return 0;
}
7、std::any_of
- std::any_of:检查区间[first, last)中是否至少有一个元素都满足一元判断式p,只要有一个元素满足条件就返回true,否则返回false。false。
- std::any_of源码
// any_of 源码
template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 bool any_of(const _InIt _First, const _InIt _Last, _Pr _Pred) {
// test if any element satisfies _Pred
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
for (; _UFirst != _ULast; ++_UFirst) {
if (_Pred(*_UFirst)) {
return true;
}
}
return false;
}
// 当传入容器为空,返回false
- 实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void test()
{
auto isEven = [](int i) {return i % 2 != 0; };
vector<int> v1 = { 1, 3, 5, 7, 8, 9 };
bool anyof = std::any_of(v1.begin(), v1.end(), isEven); // 注意:当v1为空时,返回false
if (anyof)
cout << "at least one is even" << endl;
}
int main()
{
test();
return 0;
}
8、std::minmax_element
- std::minmax_element :同时获取最大值和最小值的算法minmax_element
- std::minmax_element 源码
// minmax_element 源码
template <class _FwdIt, class _Pr>
_NODISCARD constexpr pair<_FwdIt, _FwdIt> minmax_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred) {
// find smallest and largest elements
_Adl_verify_range(_First, _Last);
const auto _Result = _Minmax_element_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Pass_fn(_Pred));
_Seek_wrapped(_Last, _Result.second);
_Seek_wrapped(_First, _Result.first);
return {_First, _Last};
}
template <class _FwdIt>
_NODISCARD constexpr pair<_FwdIt, _FwdIt> minmax_element(_FwdIt _First, _FwdIt _Last) {
// find smallest and largest elements
return _STD minmax_element(_First, _Last, less<>{});
}
- 实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void test()
{
auto isEven = [](int i) {return i % 2 != 0; };
vector<int> v1 = { 1, 3, 5, 7, 8, 9 };
// 同时获取最大值和最小值的算法minmax_element
auto maxmin = minmax_element(v1.begin(), v1.end());
cout << *maxmin.first << " " << *maxmin.second << endl;
}
int main()
{
test();
return 0;
}
9、std::copy_if
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int test()
{
std::vector<int> v1{ 1, 2, 3, 4, 5 }, v2(v1.size());
auto it = std::copy_if(v1.begin(), v1.end(), v2.begin(), [](auto& i) { return (i % 2 == 1); });
v2.resize(std::distance(v2.begin(), it));
std::for_each(v2.begin(), v2.end(), [](auto& e) {cout << e << " "; }); // 1 3 5
cout << endl;
return 0;
}
int main()
{
test();
return 0;
}
10、std::iota()
此函数用于为数组分配连续值。此函数接受3个参数,即数组名称、大小和起始编号。
#include<iostream>
#include<numeric> // for iota()
using namespace std;
int main()
{
// Initializing array with 0 values
int ar[6] = {0};
// Using iota() to assign values
iota(ar, ar+6, 20);
// Displaying the new array
cout << "The new array after assigning values is : ";
for (int i=0; i<6 ; i++)
cout << ar[i] << " "; // 20 21 22 23 24 25
return 0;
}
11、std::partition(),std::is_partitioned()
partition(beg,end,condition):-此函数用于根据参数中提到的条件对元素进行分区。
is_partitioned(beg,end,condition):-如果容器已分区,则此函数返回布尔值true,否则返回false。
#include<iostream>
#include<algorithm> // for partition algorithm
#include<vector> // for vector
using namespace std;
int main()
{
// Initializing vector
vector<int> vect = { 2, 1, 5, 6, 8, 7 };
// Checking if vector is partitioned
// using is_partitioned()
is_partitioned(vect.begin(), vect.end(), [](int x)
{
return x%2==0;
})
?
cout << "Vector is partitioned"
:
cout << "Vector is not partitioned";
cout << endl;
// partitioning vector using partition()
partition(vect.begin(), vect.end(), [](int x)
{
return x%2==0;
});
// Checking if vector is partitioned
// using is_partitioned()
is_partitioned(vect.begin(), vect.end(), [](int x)
{
return x%2==0;
})
?
cout << "Now, vector is partitioned after partition operation"
:
cout << "Vector is still not partitioned after partition operation";
cout << endl;
// Displaying partitioned Vector
cout << "The partitioned vector is : ";
for (int &x : vect) cout << x << " "; // 2 8 6 5 1 7
return 0;
}
12、std::stable_partition(),std::partition_point()
stable_partition(beg,end,condition):-此函数用于根据参数中提到的条件对元素进行分区,从而保持元素的相对顺序。。
partition_point(beg,end,condition):-此函数返回一个迭代器,该迭代器指向容器的分区点,即分区范围[beg,end]中条件不为true的第一个元素。容器应该已经分区,此函数才能工作。
// C++ code to demonstrate the working of
// stable_partition() and partition_point()
#include<iostream>
#include<algorithm> // for partition algorithm
#include<vector> // for vector
using namespace std;
int main()
{
// Initializing vector
vector<int> vect = { 2, 1, 5, 6, 8, 7 };
// partitioning vector using stable_partition()
// in sorted order
stable_partition(vect.begin(), vect.end(), [](int x)
{
return x%2 == 0;
});
// Displaying partitioned Vector
cout << "The partitioned vector is : ";
for (int &x : vect) cout << x << " "; // 2 6 8 1 5 7
cout << endl;
// Declaring iterator
vector<int>::iterator it1;
// using partition_point() to get ending position of partition
auto it = partition_point(vect.begin(), vect.end(), [](int x)
{
return x%2==0;
});
// Displaying partitioned Vector
cout << "The vector elements returning true for condition are : ";
for ( it1= vect.begin(); it1!=it; it1++)
cout << *it1 << " "; // 2 6 8
cout << endl;
return 0;
}
13、std::partition_copy()
partition_copy(beg,end,beg1,beg2,condition):-此函数复制参数中提到的不同容器中的分区元素。它需要5个参数。容器的开始和结束位置、必须复制元素的新容器的开始位置(条件返回为true的元素)、必须复制其他元素的新的容器的起始位置(条件为false的元素)和条件。此功能需要调整新容器的大小。
// C++ code to demonstrate the working of
// partition_copy()
#include<iostream>
#include<algorithm> // for partition algorithm
#include<vector> // for vector
using namespace std;
int main()
{
// Initializing vector
vector<int> vect = { 2, 1, 5, 6, 8, 7 };
// Declaring vector1
vector<int> vect1;
// Declaring vector1
vector<int> vect2;
// Resizing vectors to suitable size using count_if() and resize()
int n = count_if (vect.begin(), vect.end(), [](int x)
{
return x%2==0;
} );
vect1.resize(n);
vect2.resize(vect.size()-n);
// Using partition_copy() to copy partitions
partition_copy(vect.begin(), vect.end(), vect1.begin(),
vect2.begin(), [](int x)
{
return x%2==0;
});
// Displaying partitioned Vector
cout << "The elements that return true for condition are : ";
for (int &x : vect1)
cout << x << " "; // 2 6 8
cout << endl;
// Displaying partitioned Vector
cout << "The elements that return false for condition are : ";
for (int &x : vect2)
cout << x << " "; // 1 5 7
cout << endl;
return 0;
}
14、std::apply(),std::sum()
apply():-此函数将其参数中给定的操作一次应用于所有valarray元素,并返回一个具有操作值的新valarray。
sum():-此函数一次返回valarrays的所有元素的总和。
#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
// Initializing valarray
valarray<int> varr = { 10, 2, 20, 1, 30 };
// Declaring new valarray
valarray<int> varr1 ;
// Using apply() to increment all elements by 5
varr1 = varr.apply([](int x){return x=x+5;});
// Displaying new elements value
cout << "The new valarray with manipulated values is : ";
for (int &x: varr1) cout << x << " "; // 15 7 25 6 35
cout << endl;
// Displaying sum of both old and new valarray
cout << "The sum of old valarray is : ";
cout << varr.sum() << endl; // 63
cout << "The sum of new valarray is : ";
cout << varr1.sum() << endl; // 88
return 0;
}
15、std::min(),std::max()
min():-此函数返回valarray的最小元素。
max():-此函数返回valarray的最大元素。
#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
// Initializing valarray
valarray<int> varr = { 10, 2, 20, 1, 30 };
// Displaying largest element of valarray
cout << "The largest element of valarray is : ";
cout << varr.max() << endl; // 30
// Displaying smallest element of valarray
cout << "The smallest element of valarray is : ";
cout << varr.min() << endl; // 1
return 0;
}
16、std::shift(),std::cshift()
shift():-此函数在按参数中提到的数字移动元素后返回新的valarray。如果数字为正,则应用左移,如果数字为负,则应用右移。
cshift():-此函数在按参数中提到的数字循环移动(旋转)元素后返回新的valarray。如果数字为正,则应用左循环移位,如果数字为负,则应用右循环移位。
// C++ code to demonstrate the working of
// shift() and cshift()
#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
// Initializing valarray
valarray<int> varr = { 10, 2, 20, 1, 30 };
// Declaring new valarray
valarray<int> varr1;
// using shift() to shift elements to left
// shifts valarray by 2 position
varr1 = varr.shift(2);
// Displaying elements of valarray after shifting
cout << "The new valarray after shifting is : ";
for ( int&x : varr1) cout << x << " "; // 20 1 30 0 0
cout << endl;
// using cshift() to circularly shift elements to right
// rotates valarray by 3 position
varr1 = varr.cshift(-3);
// Displaying elements of valarray after circular shifting
cout << "The new valarray after circular shifting is : ";
for ( int&x : varr1) cout << x << " "; // 20 1 30 10 2
cout << endl;
return 0;
}