STL— 函数
转自百度百科
主要记录写题时遇到的 STL 的一些函数, 这里函数的区间几乎都是半开的。
1,sort(start, end, cmp)
头文件:<algorithm>
时间复杂度:nlog2n
升序:默认升序
降序:加一个比较函数
bool complare(int a, int b) { return a > b; }
一,离散化
string s[10005]; vector<string>v; int main(void) { while (scanf("%d", &n) != EOF) { v.clear(); for (int i = 0; i < n; i++) { cin >> s[i]; v.push_back(s[i]); } sort(v.begin(), v.end()); int lon = unique(v.begin(), v.end()) - v.begin(); for (int i = 0; i < n; i++) { printf("%d\n", lower_bound(v.begin(), v.begin() + lon, s[i]) - v.begin() + 1); } } return 0; }
1,迭代器:可以看成是复杂的指针
迭代器相减:可以看成指向同一数组的指针相减,最后结果为 int 类型,代表指针所指向的两个元素的位置距离
2,unique:
本质:STL 函数,包含于 algotithm 头文件中。功能是将数组中相邻的重复元素去除。
然而其本质是将重复的元素移动到数组的末尾,最后再将迭代器末尾指向最后不重复的下标。所以容器最后长度没有变化
返回值:返回一个迭代器,指向重复元素的首地址
功能:unique函数可以去除数组中相邻重复项
所以,想要实现完全去重功能,需要在执行 unique 函数之前先对数组进行排序
例题:求第k小的数,不计相同的数
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<algorithm> using namespace std; int a[10010]; int main(void) { int n, k; scanf("%d%d", &n, &k); for (int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); int cnt = unique(a, a + n) - a; // 迭代器相减为int if (cnt < k) printf("NO RESULT"); else printf("%d", a[k - 1]); system("pause"); return 0; }
3,
lower_bound
返回值:返回一个迭代器, 它指向在 [first,last) , 标记的有序数列中可以插入 value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于等于 value 的值
upper_bound
返回值:返回一个迭代器, 它指向在 [first,last) 标记的有序数列中可以插入 value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于 value 的值
注意:调用 lower_bound 和 lower_bound 之前必须确定序列为有序序列,否则调用出错。
例如:map中已经插入了1,2,3,4的话,
如果l lower_bound(2),返回的迭代器指向 2,
而 upper_bound(2) ,返回的迭代器指向 3
如果想要查找 小于 x 的最大值 用 --lower_bound 就可以了
如果想要查找 小于等于 x 的最大值 用 --upper_bound 就可以了
这俩个有可能越界,需要特判一下
不过,注意所有越界都是返回 指向 end 的迭代器
如代码
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<math.h> #include<set> using namespace std; int main(void) { set<int>s; s.insert(5); s.insert(4); if (--s.begin() == s.end()) printf("what\n"); system("pause"); return 0; }
例题:http://www.fjutacm.com/Problem.jsp?pid=2490
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<math.h> #include<set> using namespace std; #define ll long long int min(int a, int b) { return a < b ? a : b; } int main(void) { set<int>s; int n; while (scanf("%d", &n)!=EOF) { s.clear(); ll sum = 0; while (n--) { int x; scanf("%d", &x); if (s.empty()) { sum += x; s.insert(x); } else { auto l = --s.upper_bound(x); auto r = s.lower_bound(x); if (l == s.end()) l = s.begin(); if (r == s.end()) r--; int a = abs(*l - x); int b = abs(*r - x); int t = min(a, b); sum += t; s.insert(x); } } printf("%lld\n", sum); } return 0; }
二,求瑶瑶的第 K 大
选择快排的实现
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<functional> #include<algorithm> #include<queue> using namespace std; #define N int(2e6+5) int a[N], b, c; int partition(int L, int R) { int p = a[R]; int i = L - 1, j = L; while (i + 1 <= R) { i++; if (a[i] >= p) { int t = a[i]; a[i] = a[j]; a[j] = t; j++; } } return j - 1; } void qs(int L, int R) { if (L >= R) return; int m = partition(L, R); if (c - 1 == m) // 快排的有选择的进行排序 return; if (m > c - 1) qs(L, m - 1); else qs(m + 1, R); } void scan(int &x) { char c; do c = getchar(); while (c<'0' || c>'9'); x = c - '0'; while ('0' <= (c = getchar()) && c <= '9') x = x * 10 + c - '0'; } void print(int a) { if (a > 9) print(a / 10); putchar(a % 10 + '0'); } int main(void) // 快排优化 { while (scanf("%d%d", &b, &c) != EOF) { for (int i = 0; i < b; i++) scan(a[i]); qs(0, b - 1); print(a[c - 1]); puts(""); } return 0; } int main2(void) { int n, k; scanf("%d%d", &n, &k); for (int i = 0; i<n; i++) scanf("%d", &a[i]); nth_element(a, a + k - 1, a + n, greater<int>()); printf("%d", a[k - 1]); system("pause"); return 0; }
1,less() 和 greater()
两个函数的头文件是<functional>
less(): 类似于 < 的作用,用于比较两个值的大小,但是是泛型函数,支持大多数类型的值比较
greater: 类似于 > 的作用,用于比较两个值的大小,但是是泛型函数,支持大多数类型的值比较
2,nth_element
头文件: <algorithm>
功能:对给定范围进行排序
参数: nth_element (first , nth , last , comp)
first,last: 随机访问迭代器.指定了需要重新"排序"的范围.包括 first ,但不包括 last.
nth: 随机访问迭代器.指向范围[first,last)内的一个位置.这个位置将放置排序后应该放于此位置的元素
comp: 二元函数. 返回值需为 bool 类型, 表明是否第一个参数应该排序到第二个参数的前面. 此函数不应该修改参数值.可以是一个函数指针或函数对象.
总之:
对给定范围[first,last)内的元素进行重新布置.
方法是,nth 位置的元素放置的值就是把所有元素排序后在 nth 位置的值.把所有不大于 nth 的值放到 nth 的前面,把所有不小于 nth 的值放到 nth 后面.
它的代码实现应该类似于 选择快排
======== ======== ======== ======== ====== ====== ===== === == =
一剪梅·舟过吴江 蒋捷 宋
何日归家洗客袍?银字笙调,心字香烧。流光容易把人抛,红了樱桃,绿了芭蕉。