c++STL 高效函数应用总结

一.三种二分查找函数(下面使用时都必须排序)

头文件:

#include<algorithm>

1.binary_search()

(1)功能:查找某个元素是否出现,其返回值是bool,若找到这个元素返回真,否则返回假。

(2)模板:

数组中:binary_search(num,num+n,k)//在num数组中找元素k

vector中:binary_search(num.begin(),num.end(),k)//在num容器里找k

set中:binary_search(num.begin(),num.end(),k)//在num容器里找k,但是set中count和find函数提供了查找功能

2.lower_bound()

(1)功能:返回 第一个 大于等于元素的位置(该位置是指针或者迭代器),如果所有元素都小于k,则返回最后一个位置last,注意最后一个last是越界的!

(2)模板:

<1>数组:lower_bound(num,num+n,k)//在数组num里查找大于等于k的位置(从0开始)

int pos=lower_bound(num,num+n,k)-num;(指针相减即为位置坐标,若没有则pos==n)

<2>vector:lower_bound(num.begin(),num.end(),k)

int pos=lower_bound(num.begin(),num.end(),k)-num.begin();//迭代器相减即为坐标位置

<3>set:   num3.lower_bound(k);  //set,map自带lower_bound和upper_bound函数!返回迭代器,不过set和map中没有像vector和数组中排序的概念,所以迭代器不能相减!!


3.upper_bound()

(1)功能:返回第一个 大于 元素k的位置,若没有返回last同  上。

                 模板功能同上不再赘述

详情点击:点击打开链接

例题:HDU2141 Can you find it?

传送门:点击打开链接

题意:给三个数组a,b,c和数字X,问能否找到a+b+c=X

思路:枚举ab,二分查找X-a-b在c中有没有;或者创建a+b新数组,枚举c,判断X-c在(a+b)数组里有没有出现。

代码:

#include <iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
long long int numA[505];
long long int numB[505];
long long int numC[505];
long long int all[1000000];
int main()
{
    int l,n,m;
    int t=0;
    while(scanf("%d%d%d",&l,&n,&m)!=EOF)
    {
        t++;
        int i;
        for(i=0; i<l; i++)
        {
            scanf("%lld",&numA[i]);
        }
        int j;
        for(j=0; j<n; j++)
        {
            scanf("%lld",&numB[j]);
        }
        int k;
        for(k=0; k<m; k++)
        {
            scanf("%lld",&numC[k]);
        }
        int s;
        scanf("%d",&s);
        printf("Case %d:\n",t);
        int len=0;
        for(int p=0;p<i;p++)
        {
            for(int q=0;q<j;q++)
            {
                all[len++]=numA[p]+numB[q];
            }
        }
        sort(all,all+len);
        sort(numC,numC+k);
        int len2=unique(all,all+len)-all;
        int k2=unique(numC,numC+k)-numC;
        while(s--)
        {
            long long int X;
            bool judge=false;
            scanf("%lld",&X);
            for(int m=0;m<k2;m++)
            {
                long long int ans=X-numC[m];
                if(binary_search(all,all+len2,ans))
                {
                    judge=true;
                    break;
                }
            }
            if(judge)
                puts("YES");
            else
                puts("NO");

        }

    }
    return 0;
}

二.求集合函数

见文章:点击打开链接


三.全排列函数

头文件:

#include<algorithm>

(1)概念:“下一个排列组合”和“上一个排列组合”,对序列 {a, b, c},每一个元素都比后面的小,按照字典序列,固定a之后,a比bc都小,c比b大,它的下一个序列即为{a, c, b},而{a, c, b}的上一个序列即为{a, b, c},同理可以推出所有的六个序列为:{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a},其中{a, b, c}没有上一个元素,{c, b, a}没有下一个元素。

(2)函数功能: 返回值为bool类型,当当前序列不存在下一个排列或者上一个排列时,函数返回false,否则返回true,排列好的数在容器中存储,

(3)模板:(全排列函数是会更改容器内容的!)

〈1〉next_permutation:求下一个排列组合

数组:next_permutation(arr, arr+size);

vector:next_permutation(arr.begin(), arr.end());

注意:在使用前需要对欲排列数组按 *升序* 排序,否则只能找出该序列之后的全排列数。

    比如,如果数组num初始化为2,3,1,那么输出就变为了:{2 3 1} {3 1 2} {3 2 1}

<2>prev_permutation:求上一个排列组合

数组:next_permutation(arr, arr+size);

vector:next_permutation(arr.begin(), arr.end());

注意:在使用前需要对欲排列数组按降序排序,否则只能找出该序列之后的全排列数。

(4)常用算法模板

 do
     {
         for(int i=0;i<5;i++)
            cout<<num2[i]<<" ";
         cout<<endl;
     }while(next_permutation(num3.begin(),num3.end()));

(5)例题

Poj2718 Smallest Difference

传送门:点击打开

题意:给出最多10个数字,将它们划分为两个整数,求差值最小的值(除非只有一位数,否则不允许出现先导0)

思路:很显然如果总共有n个数,必然有一个整数长n/2,另一个长n-n/2,暴力枚举全排列,求最小差值!

代码:

#include <iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
#define INF 0x3f3f3f3f
int num[15];
int main()
{
    int T;
    cin>>T;
    getchar();
    while(T--)
    {
        int a;
        int len=0;
        string s;
        getline(cin,s);
        for(int i=0; i<s.size(); i++)//输入题目没说eof就是以换行结束!只能字符串!!
        {
            if(s[i]>='0'&&s[i]<='9')
                num[len++]=s[i]-'0';
        }
        if(len==2)
            cout<<num[1]-num[0]<<endl;
        else
        {
            int minn=INF;
            do
            {
                int mid=len/2;
                if(!num[0]||!num[mid])
                    continue;
                int sum1=0,sum2=0;
                for(int i=0; i<mid; i++)
                {
                    sum1*=10;
                    sum1+=num[i];
                }
                for(int i=mid; i<len; i++)
                {
                    sum2*=10;
                    sum2+=num[i];
                }
                minn=min(minn,abs(sum1-sum2));

            }
            while(next_permutation(num,num+len));
            cout<<minn<<endl;
        }
    }

    return 0;
}


四:去重函数

(1) unique()是C++标准库函数里面的函数,其功能是去除相邻的重复元素(只保留一个),所以使用前需要对数组进行排序!!它会把重复的元素添加到容器末尾(所以数组大小并没有改变),而返回值是去重之后的尾地址.

(2)模板

数组:

   sort(num,num+12);
   int len=unique(num,num+12)-num;//去重后的长度
vector:
    sort(num2.begin(),num2.end());
    int len=unique(num2.begin(),num2.end())-num2.begin();

猜你喜欢

转载自blog.csdn.net/qq_40772692/article/details/79940993