STL查找算法
-
基本查找
-
find:区间查找
-
find_if:条件查找
-
find_firt_of: 查找区间第一次出现值
-
adjacent_find: 查找第一次重复的数
-
search:子序列查找
-
search_n: 子序列查找出现次数
-
-
统计查找
-
count: 区间统计
-
count_if: 条件统计个数
-
equal:比较
-
-
有序查找
-
binary_search:二分查找
-
upper_bound: 查找最后一个大于查找的值
-
lower_bound: 大于等于查找的值
-
equal_range:区间比较---有序序列
-
/*
+ + find:区间查找
+ find_if:条件查找
+ find_firt_of: 查找区间第一次出现值
+ adjacent_find: 查找第一次重复的数
+ search:子序列查找
+ search_n: 子序列查找出现次数
+ 统计查找
+ count: 区间统计
+ count_if: 条件统计个数
+ equal:比较
+ 有序查找
+ binary_search:二分查找
+ upper_bound: 查找最后一个大于查找的值
+ lower_bound: 大于等于查找的值
+ equal_range:区间比较---有序序列
*/
#include<iostream>
#include<algorithm> //c++stl算法头文件
#include<numeric> //数字处理类的头文件
#include<functional> //仿函数头文件
#include<vector>
#include<list>
using namespace std;
template<class _Ty>void print(_Ty data) {
for (auto v : data) {
cout << v << " ";
}
cout << endl;
}
int main() {
int array[] = { 1,2,3,4,6,5,8,9,7 };
vector<int> vec;
vec.assign(array, array + 10);
//大部分查找返回的是一个迭代器,可以用auto推断
auto result = find(vec.begin(), vec.end(), 7); //找自定义类型要重载=运算符\
//没找到返回容器结束的位置
if (result != vec.end()) {
cout << *result << endl;
}
//2.条件查找find_if
auto findIf = find_if(vec.begin(), vec.end(), [](int x)mutable noexcept->bool {return x > 3; }); //第一个大于3的就会返回
cout << *findIf << endl;
//3.find_first_of 和string要区分
int temp[] = { 99,2,1 };
auto findFirstOf = find_first_of(vec.begin(), vec.end(), temp, temp + 3);//从一个区间找另一个区间,只要找到就返回
cout << *findFirstOf << endl; //这里返回1,因为先遍历vec.begin(), vec.end()这个区间,和temp-temp+3区间比,找到就返回
//4.查找重复的元素
vector<int> revec = { 1,2,2,2,3,3,1,6,2,4,88,99,100 };
auto reIter = adjacent_find(revec.begin(), revec.end());
if (reIter != revec.end()) {
cout << *reIter << endl;
}
//5.找子串
int searchData[] = { 3,3,1 };
auto sonData = search(revec.begin(), revec.end(), searchData, searchData + 3);
cout << *sonData << endl; //返回的是子串第一个元素的位置
//6.找重复出现的元素
auto searchN = search_n(revec.begin(), revec.end(), 3, 2);
if (searchN != revec.end())
cout << *searchN << endl;
//search是有重载的
//找连续三个满足lambda表达式的值(此处三个连续大于2的值)
searchN = search_n(revec.begin(), revec.end(), 3, 2, [](int a, int b) {return a > b; });
cout << *searchN << endl;
//7.统计出现的次数 返回一个int类型
cout << count(revec.begin(), revec.end(), 3) << endl;
//8.条件统计
cout << count_if(revec.begin(), revec.end(), [](int x) {return x > 60; }) << endl;
//9.比较
list<int> myList = { 1,2,2,2,3,3,1,6,2,4,88,99,100 };
cout << boolalpha << equal(revec.begin(), revec.end(), myList.begin(), myList.end()) << endl;
//有序操作(原容器的数据必须是有序的)
//10.二分查找
vector<int> testData = { 1,2,3,4,5,6,7,8,9 };
//binary_search
cout << boolalpha << binary_search(testData.begin(), testData.end(), 2) << endl;
//11.大于(不包括等于)
auto uper = upper_bound(testData.begin(), testData.end(), 6);
cout << *uper << endl;
//12.大于等于
auto lower = lower_bound(testData.begin(), testData.end(), 6);
cout << *lower << endl;
//12.包含以上两个结果,返回一个数对类型(pair)所以打印的时候要first和second,仍然是迭代器
pair<vector<int>::iterator, vector<int>::iterator> temp= equal_range(testData.begin(), testData.end(), 6);//这里的auto如果写全
auto pairData = equal_range(testData.begin(), testData.end(), 6);
cout << *pairData.first << "\t" << *pairData.second << endl;
return 0;
}
STL排序通用算法
-
merge: 归并排序,存于新容器
-
inplace_merge: 归并排序,覆盖原区间
-
sort: 排序,更改原容器顺序
-
stable_sort: 排序,保存原容器数据顺序
-
nth_element: 关键字排序
-
partition:范围排序
-
partial_sort:范围排序
-
partial_sort_copy:范围排序外加复制操作
-
stable_partition: 范围排序,保存原容器顺序
-
random_shuffle: 随机排序
-
reverse:逆序原容器
-
reverse_copy: 逆序容器保存到新容器
-
rotate:移动元素到容器末尾
-
rotate_copy:移动元素到新容器
-
/* - merge: 归并排序,存于新容器 - inplace_merge: 归并排序,覆盖原区间 - sort: 排序,更改原容器顺序 - stable_sort: 排序,保存原容器数据顺序 - nth_element: 关键字排序 - partition:范围排序 - partial_sort:范围排序 - partial_sort_copy:范围排序外加复制操作 - stable_partition: 范围排序,保存原容器顺序 - random_shuffle: 随机排序 - reverse:逆序原容器 - reverse_copy: 逆序容器保存到新容器 - rotate:移动元素到容器末尾 - rotate_copy:移动元素到新容器 注意list排序和上面都不一样,用的是内置的排序sort,不能用公共的排序 */ #include<iostream> #include<algorithm> //c++stl算法头文件 #include<numeric> //数字处理类的头文件 #include<functional> //仿函数头文件 #include<vector> #include<list> #include<ctime> using namespace std; template<class _Ty>void print(_Ty data) { for (auto v : data) { cout << v << " "; } cout << endl; } class MM { public: MM(string name,int age):name(name),age(age){} void print() { cout << name << "\t" << age << endl; } string getName() { return name; } int getAge() { return age; } protected: string name; int age; }; void testSortUserData() { //测试手动重写仿函数(制定排序准则) vector<MM> mmData; mmData.push_back(MM("小芳", 18)); mmData.push_back(MM("小张", 15)); mmData.push_back(MM("小王", 13)); sort(mmData.begin(), mmData.end(), [](auto a, auto b) {return a.getAge() < b.getAge(); }); for (auto v : mmData) { v.print(); } //1.sort算法 vector<int> vec = { 1,2,3,4,5,0,9,8,7,6 }; sort(vec.begin(), vec.end()); //默认排序 sort(vec.begin(), vec.end(), less<int>()); //从大到小 sort(vec.begin(), vec.end(), greater<int>()); } bool com_as_int(double a, double b) { return int(a) < int(b); } //2.保持元素的相对位置排序 void testStableSort() { vector<double> num = { 1.33,2.33,1.22,3.22,3.55,3.66 }; stable_sort(num.begin(),num.end(), com_as_int); print(num); //7.保持原容器顺序,变化存入新容器 vector<int> result(num.size()); stable_partition(num.begin(), num.end(), bind(com_as_int,std::placeholders::_1,2.0)); print(num); } //3.归并排序(一定要是有序的,归并排序不会更改原容器) (将两个有序数列合并,这里举例用一个容器,可以用两个容器) void testMerge() { vector<int> vec = { 1,2,3,4,5,0,6,7,8,9 }; vector<int> result(vec.size()); merge(vec.begin(), vec.begin() + 5, vec.begin() + 5, vec.end(), result.begin()); print(result); //4.改变原容器 inplace_merge(vec.begin(), vec.begin() + 5, vec.end()); print(vec); } void testnth_element() { //5.关键字排序(按照关键字,大于放左边,小于放右边) vector<int> test = { 1,2,8,4,5,0,3,6,7,9 }; nth_element(test.begin(), test.begin() + 5, test.end()); print(test); } void testPartition() { //6.分类处理(改变原容器) //通过子函数描述条件,返回true放在左边,返回false放在右边 vector<int> vec = { 98,10,98,23,45,65,34,56,67 }; partition(vec.begin(), vec.end(), [](int a) {return a > 60; }); print(vec); } void testPartial_sort() { //8.局部排序(排单独的几个元素) vector<int> num = { 22,33,45,8,23,66,45,34,244 }; partial_sort(num.begin(), num.begin() + 5, num.end()); print(num); //9.局部排序(结果另存) vector<int> result(5); partial_sort_copy(num.begin(), num.begin() + 5, result.begin(), result.begin() + 5); print(result); } void testRandom_shuffle() { //10.乱序算法,如果需要每次结果都不用就需要随机函数种子 vector<int> num = { 22,33,45,8,23,66,45,34,244 }; srand((unsigned int)time(nullptr)); random_shuffle(num.begin(), num.end()); print(num); } void testReverse() { //11.逆序反转 vector<int> test = { 1,2,8,4,5,0,3,6,7,9 }; reverse(test.begin(), test.end()); print(test); //12.反转另存 vector<int> result(test.size()); reverse_copy(test.begin(), test.end(), result.begin()); print(result); } void testRotate() { //13.移位操作(把某个元素移动到末尾) vector<int> num = { 1,2,3,4,5 }; rotate(num.begin(), num.begin() + 2, num.end()); print(num); //14.移位另存 vector<int> result(num.size()); rotate_copy(num.begin(), num.begin() + 2, num.end(), result.begin()); print(result); } int main() { testStableSort(); testMerge(); testnth_element(); testPartition(); testPartial_sort(); testRandom_shuffle(); testReverse(); testRotate(); return 0; }
/* + copy: 拷贝函数 + copy_backward: 逆序拷贝 + remove: 删除 + remove_copy: 删除元素复制到新容器 + remove_if:条件删除 + remove_copy_if:条件删除拷贝到新容器 + replace:替换 + replace_copy: 替换,结果放到新容器 + replace_if: 条件替换 + replace_copy_if:条件替换,结果另存 + swap: 交换 + iter_swap: 交换 + swap_range:区间交换 + unique:去重 + unique_copy:去重,结果另存 ## */ #include<iostream> #include<algorithm> #include<vector> #include<list> #include<functional> using namespace std; template<class _Ty>void print(_Ty data) { for (auto v : data) { cout << v << " "; } cout << endl; } void testCopy() { //1.正向拷贝 vector<int> vec = { 1,2,3,4,5,6 }; list<int> myList; vector<int> nvec(vec.size()); //copy(vec.begin(), vec.end(), myList.begin()); //报错,列表创建的时候没有长度,所以无法拷贝 copy(vec.begin(), vec.end(), nvec.begin()); print(nvec); //2.逆向拷贝(从最后开始赋值) vector<int> rvec(vec.size()); copy_backward(vec.begin(), vec.end(), rvec.end()); print(rvec); } void testRemove() { //3.删除(注意不会影响原容器元素(伪删除)) 如果没找到,返回迭代器 真正的删除要用erase vector<int> vec = { 1,2,3,4,3,6 }; auto it = remove(vec.begin(), vec.end(), 3); cout << vec.size() << endl; print(vec); } void testRemove_copy() { //4.伪删除,结果另存 vector<int> vec = { 1,2,3,4,5,6 }; vector<int> rcvec(vec.size() - 1); remove_copy(vec.begin(), vec.end(), rcvec.begin(),2); print(rcvec); } void testRemove_if() { //5.条件删除 lambda表达式 vector<int> score = { 98,34,78,12,87,44,76 }; remove_if(score.begin(), score.end(), [](int x) {return x < 60; }); print(score); //6.条件删除,结果另存 vector<int> nvec(count_if(score.begin(), score.end(), [](int x) {return x > 60; })); remove_copy_if(score.begin(), score.end(), nvec.begin(), [](int x) {return x < 60; }); print(nvec); } void testReplace() { //7.替换算法(修改) 替换所有 vector<int> vec = { 1,2,3,4,5,6,7,12,1,3,4,1,2,3 }; //把所有元素替换成某个元素 replace(vec.begin(), vec.end(), 1, 100); print(vec); //8.替换后结果另存 vector<int> nevec(vec.size()); replace_copy(vec.begin(), vec.end(), nevec.begin(), 100, 0); print(nevec); //9.条件替换 replace_if(vec.begin(), vec.end(), [](int x) {return x < 5; }, 0); print(vec); //10.条件替换,结果另存 vector<int> ricvec(vec.size()); replace_copy_if(vec.begin(), vec.end(), ricvec.begin(), [](int x) {return x == 0; }, 1); print(ricvec); } void testIter_swap() { //11.交换 迭代器交换 vector<int> vec = { 1,2,3,4,5,6,7,8,9 }; iter_swap(vec.begin(), vec.end() - 1); print(vec); //12.swap 优点:不需要两个容器长度一样 只能相同容器 vector<int> vec2 = { 12,21 }; swap(vec, vec2); print(vec); //{ 12,21 } print(vec2); //{ 1,2,3,4,5,6,7,8,9 } //13.区间交换 swap_ranges(vec2.begin(), vec2.begin() + 1, vec.begin()); print(vec2); } void testUnique() { //14.去重,把容器中相同的元素去掉,只保留一个(连续的只保留一个) //两种方法完全去重,1.排序后去重,2.插入到set集合中去,自动 去重 vector<int> vec = { 1,1,2,2,3,3,3,1,1,4,4,4,4 }; //unique(vec.begin(), vec.end()); print(vec); //15.去重另存 vector<int> nvec(vec.size()); unique_copy(vec.begin(), vec.end(), nvec.begin()); print(nvec); } int main() { testCopy(); testRemove(); testRemove_copy(); testRemove_if(); testReplace(); testIter_swap(); testUnique(); return 0; }