STL中的unique()和lower_bound ,upper_bound
unique():
作用:unique()的作用是去掉容器中相邻元素的重复元素(数组可以是无序的,比如数组可以不是按从小到大或者从大到小的排列方式)
使用方法:unique(初始地址,末地址);
这里要注意的是:
1.unique()函数返回值不是去重后容器中元素的数量,而是去重后容器中的末地址。也就是说,如果想得到去重后容器中元素的数量的话还要减去初始地址。
2.unique函数在去重的时候不会扔掉重复元素,而是会把它放在容器的末尾,也就是说数组的长度一直没有变化。
举一个例子:
#include<bits/stdc++.h>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main(){
int n;
cin>>n;
int a[n+5];
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n,cmp);
int m=unique(a+1,a+1+n)-(a+1);
cout<<m<<endl;
return 0;
}
跑一下下面的程序:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[n+5];
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
int m=unique(a+1,a+1+n)-(a+1);
cout<<m<<endl;
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}
会发现,其实unique之后的数组的长度一直没有变,然后去重了之后数组的最后几位会变成原来排序后的数组的最后几位。
看运行结果:
5
4 6 9 9 4 // 输入的数组
4 4 6 9 9 // 排序后的数组
3 //去重后的值
4 6 9 9 9 //去重后数组的内容
由于去重了两个数字,所以去重后的数组最后两位和排序后数组的最后两位相同。
10
3 3 3 3 5 9 7 2 1 9
1 2 3 3 3 3 5 7 9 9
6
1 2 3 5 7 9 5 7 9 9
这个案例也是如此
STL中还有函数 lower_bound,upper_bound。
lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
程序如下:
#include<iostream>
#include<algorithm>
using namespace std;
int a[5]={1,2,3,4,5};
int main(){
sort(a,a+5);
int t1=lower_bound(a,a+5,3)-a;
int t2=upper_bound(a,a+5,3)-a;
cout<<t1<<endl;
cout<<t2<<endl;
return 0;
}
运行结果:
2
3