随笔 - 14  文章 - 1  评论 - 0  阅读 - 1965

STL 算法小结

https://blog.csdn.net/codedz/article/details/110493577 仅供学习 部分内容有改动

1.sort()快排

函数原型:sort(起始地址, 末尾地址, cmp),其中cmp是可以自己定义的函数名.

  • 数组排序示例
#include<bits/stdc++.h>

using namespace std;

int main(){
    int a[5] = {5,2,3,9,1};
    sort(a, a + 5);
    for(int i = 0; i < 5; i++) cout << a[i] << ' ';
    cout << endl;
    return 0;
}

输出为:1 2 3 5 9

  • vector排序示例
#include<bits/stdc++.h>

using namespace std;

int main(){
    vector<int> vec = {5,2,3,9,1};
    sort(vec.begin(), vec.end());
    for(int v : vec) cout << v << ' ';
    cout << endl;
    return 0;
}
  • 自定义cmp示例(也可对结构体排序使用)仿函数也可以使用
#include<bits/stdc++.h>

using namespace std;

bool cmp(int &a, int &b){ // 使用简单的比较函数
    return a > b;
}

int main(){
    vector<int> vec = {5,2,3,9,1};
    sort(vec.begin(), vec.end(), cmp);

	sort(vec.begin(), vec.end(), greater<int>()); // 使用仿函数
	sort(vec.begin(), vec.end(), greater<>()); // 使用仿函数
	
    for(int v : vec) cout << v << ' ';
    cout << endl;
    return 0;
}

2.reverse()逆置

函数原型:reverse(起始地址, 末尾地址);

vector示例(数组同上):

#include<bits/stdc++.h>

using namespace std;

int main(){
    vector<int> vec = {5,2,3,9,1};
    reverse(vec.begin(), vec.end());
    for(int v : vec) cout << v << ' ';
    cout << endl;
    return 0;
}

输出为:1 9 3 2 5

3.unique()去重

函数原型:unique(起始地址, 末尾地址, fun);其中fun为自定义的函数名。

如果想很好地使用unique(), 首先要对原数组进行排序

注意:unique函数去重并不是真正的去重,它是不断的将后面不重复的元素覆盖前面重复的元素,最后返回最后一个不重复的元素的地址。下面来看看示例:

#include<bits/stdc++.h>

using namespace std;

int main(){
    vector<int> vec = {1,1,2,3,3,4,4,5};
    auto pos = unique(vec.begin(), vec.end()) - vec.begin();
    //打印输出使用了unique函数后的vec
    for(int i : vec) cout << i << ' ';
    cout << endl << "最后一个不重复的元素是:" << pos << endl;
    return 0;
}

输出为:

1 2 3 4 5 4 4 5 
最后一个不重复的元素是:5

可以看出用了unique()函数并不能真正将vec去重,那么要如何做才能真正去重呢?

答案是用erase()方法,请看示例:

#include<bits/stdc++.h>

using namespace std;

int main(){
    vector<int> vec = {1,1,2,3,3,4,4,5};
    auto pos = unique(vec.begin(), vec.end());
    vec.erase(pos, vec.end());
    for(int v : vec) cout << v << ' ';
    cout << endl;
    return 0;
}

4.查找函数

二分查找函数

lower_bound(起始地址, 末尾地址, target):查找第一个大于等于target目标值的位置

upper_bound(起始地址, 末尾地址, target):查找第一个大于target目标值的位置

binary_search(起始地址, 末尾地址, target):查找target是否存在于数组或vector中,找到返回true,否则返回false

这三种方法都是采用的二分查找实现的函数,用于有序数组或vector等,查找效率较高,实际写题时,直接用能较少很多代码量。下面来看看示例吧:

#include<bits/stdc++.h>

using namespace std;

int main(){
    vector<int> vec = {1,1,2,3,3,4,4,5};
    auto pos1 = lower_bound(vec.begin(), vec.end(), 2) - vec.begin();
    auto pos2 = upper_bound(vec.begin(), vec.end(), 2) - vec.begin();
    auto flag = binary_search(vec.begin(), vec.end(), 2);
    cout << "第一个大于等于2的位置是" << pos1 << endl;
    cout << "第一个大于2的位置是" << pos2 << endl;
    cout << "查找2返回的结果:" << flag << endl;
    return 0;
}

输出如下:

第一个大于等于2的位置是2
第一个大于2的位置是3
查找2返回的结果:1
  • 字符串查找函数

s1.find(s2):在s1字符串中查找s2,查找到返回第一个字符的位置,查找失败返回s1.npos,这个其实是一个特别标志,也可以看成一个数字,是4294967295,即s1.npos=4294967295

#include<bits/stdc++.h>

using namespace std;

int main(){
    string s = "abcdabef";
    cout << s.find('b') << endl;
    cout << s.find("ab") << endl;
    cout << s.find("cda") << endl;
    cout << s.find("cde") << endl;
    return 0;
}

输出如下:

1
0
2
4294967295 // 不同的编译环境这个值可以不一样
  • set集合查找
    `set.find(a):查找a是否在set中,如果找不到,返回set.end()

set.count(a):本来是计算a出现的次数,但是由于集合中是没有重复元素的,于是count函数也就被作为查找函数了,因为a只能出现1次或者0次,查找成功,返回1;查找失败返回0.

#include<bits/stdc++.h>

using namespace std;

int main(){
    vector<int> v = {1,2,3,4};
    set<int> s(v.begin(), v.end());
    //查找2
    if (s.find(2) != s.end()) cout << "查找成功" << endl;
    else cout << "查找失败" << endl;
    return 0;
}
  • map映射查找

map.find():主要用于查找key是否存在map中,不存在返回map.end(),用法和set一样.


insert(); 插入一个数,插入的数是一个pair
 
erase(); 
 
	(1)输入是pair中的key(值), 可以删除对应的键值对
 
	(2)输入一个迭代器,删除这个迭代器 通常是与find结合使用
 
find(); 查找一个数 输入参数为key值
 
lower_bound(x); 返回大于等于x的最小的数的迭代器 输入参数为key值
 
upper_bound(x); 返回大于x的最小的数的迭代器 输入参数为key值

map的遍历方法

​    假设有个map<int,string> s;
 
​  第一种:
 
	for(map<string,int>::iterator it=m.begin();; it!=m.end(); it++) {
		cout<<it->first<<" "<<it->second<<endl;
	}
//C++中如果是个结构体(类)类型的指针,那么访问属性不能使用 . ,而是 -> 。map内部其实就是
 
//pair,其中first存的是被当成下标的部分,second存的是被当成值的部分。
 
​    第二种:
 
	for(auto it:m) {
		cout<<it.first<<" "<<it.second<<endl;
	}//C++11的新语法
	
map<int, int> map;  
    map.insert(make_pair(1, 2));  
    map.insert({3, 4});  
    map.insert({5, 6});  
    map.insert({7, 8});  
    map.insert({11, 12});  
    map.insert({10, 19});  
    map.erase({10});  
  
    auto temp = map.find(5);   //6
    cout << temp->second << endl;  
    map.erase(temp);  //删除{5, 6}
  
    for(auto it : map){  
        cout << it.second << endl;  //2, 4, 8, 12
    }  
    auto it = map.lower_bound(6);  
    cout << it->second << endl;  
//    cout << it - map.begin() << endl; //这种写法无效 红黑树的map迭代器并没有重载减法运算符

unordered_map

unordered_map是一个关联容器,存储元素时是没有顺序的,只是根据key的哈希值,将元素存在指定位置,所以根据key查找单个value时非常高效,平均可以在常数时间内完成。

unordered_map内部实现了一个哈希表,因此其元素的排列顺序是杂乱的,无序的

对于unordered_map容器,其遍历顺序与创建该容器时输入元素的顺序是不一定一致的,遍历是按照哈希表从前往后依次遍历的

`不支持lower_bound()和upper_bound()

不支持迭代器

ACM模式处理不定长输入的问题

   string temp;  //单次读取
   getline(cin, temp);  
   istringstream ss(temp);  
   vector<int> nums;  
   int num;  
   while (ss >> num) {  
   nums.push_back(num);  
   }
	
	string temp; 

	while (getline(cin, temp)) {  //循环读取
		istringstream ss(temp);
		vector<int> nums;
		int num;
		while (ss >> num) {
			nums.push_back(num);
		}
		for (auto nve : nums) cout << nve << " ";
		cout << endl;
	}

5.字符串整形转换函数

字符串转整形

stoi(s):将字符串s转化成整形,s为string类型,即string --> int

atoi(s):将字符串转化为整形,但s为const char*类型,可以先用s.c_str()方法把string类型转化为const char类型,再转为整形,即const char --> int.
原因是:
atoi()的参数是 const char
,因此对于一个字符串str我们必须调用 c_str()的方法把这个string转换成 const char类型的,而stoi()的参数是const string,不需要转化为 const char*;

stringstream:需要头文件#include,可将只含数字的字符串转化为整形,也可将数字和小数点组成的字符串转化为浮点型,即string --> int, string --> double.


using namespace std;

int main(){
    string s = "124";
    int a = stoi(s);
    s = "123.4";
    double x;
    stringstream ss;
    ss << s;
    ss >> x;
    cout << a << endl;
    cout << x << endl;
    return 0;
}

输出为:
124
123.4

整形转字符串

  1. stringstream:需要头文件#include<sstream>,可将整形或浮点型数字转化为字符串,即int --> string, double --> string
  2. to_string():可将整形转化为字符串,不推荐将浮点型转化为字符串

using namespace std;

int main(){
    double x = 12.34;
    int y = 12;
    stringstream ss;
    string s;
    ss << x;
    ss >> s;
    cout << s << endl;
    s = to_string(y);
    cout << s << endl;
    return 0;
}

12.34 
12
posted on   success_ashes  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示