C++STL算法篇(一)

本文详细介绍了C++ STL库中的查找算法(如find, find_if等)、统计查找(count, count_if),以及排序算法(merge, inplace_merge, binary_search等)。涵盖了基本查找、条件查找、有序操作和数据处理的关键技术。
摘要由CSDN通过智能技术生成

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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值