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

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

 

例题: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;
}
View Code

 

 

二,求瑶瑶的第 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;
}
View Code

 

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 后面.

它的代码实现应该类似于 选择快排

 

 

 

 

======== ======== ======== ======== ====== ====== ===== === == =

一剪梅·舟过吴江  蒋捷 宋

一片春愁待酒浇。江上舟摇,楼上帘招。秋娘渡与泰娘桥,风又飘飘,雨又萧萧。
何日归家洗客袍?银字笙调,心字香烧。流光容易把人抛,红了樱桃,绿了芭蕉。 

 

posted @ 2020-03-27 20:28  叫我妖道  阅读(245)  评论(0编辑  收藏  举报
~~加载中~~