常用函数
STL
提供了一些常用函数,包含在头文件#include<algorithm>
中。
min(x,y)
:求两个元素的最小值。max(x,y)
:求两个元素的最大值。swap(x,y)
:交换两个元素。find(begin,end,x)
:返回指向区间[begin,end)
第1个值为x
的元素指针。如果没找到,则返回end
。count(begin,end,x)
:返回指向区间[begin,end)
值为x
的元素数量,返回值为整数。reverse(begin,end)
:翻转一个序列。random_shuffle(begin,end)
:随机打乱一个序列。unique(begin,end)
:将连续的相同元素压缩为一个原数,返回去重后的尾指针。不连续的相同元素不会被压缩,因此一般先排序后去重。fill(begin,end,val)
:将区间[begin,end)
的每个元素都设置为val
。sort(begin,end,compare)
:对一个序列排序,参数begin
和end
表示一个范围,分别为待排序的首地址和尾地址;compare
表示排序的比较函数,可省略,默认为升序。stable_sort(begin,end,compare)
为稳定排序,即保持相等元素的相对位置nth_element(begin,begin+k,end,compare)
:使区间[begin,end)
第k
小的元素处在第k个位置上,左边元素都小于或等于它,右边元素都大于或等于它,但并不保证其他元素有序。lower_bound(begin,end,x)
/upper_bound(begin,end,x)
:两个函数都是利用二分查找的方法,在有序数组中查找第1个满足条件的元素,返回指向该元素的指针。next_permutation(begin,end)
/pre_permutation(begin,end)
:next_permutation()
是求按字典序的下一个排列的函数,可以得到全排列。pre_permutation()
是求按字典序的上一个排列的函数。
部分函数详解
sort(begin,end,compare)
- 使用默认的函数排序。
int main(){
int a[4] = {7,4,5,23};
sort(a,a+4);//数组a按升序排序
for(int i = 0; i<4; i++){
cout << a[i] << " ";
}
return 0;
}
- 自定义比较函数。
bool cmp(int a, int b){//比较函数
return a<b;//升序排列,如果改为return a>b,则为降序
}
int main(){
int a[4] = {7,4,5,23};
sort(a,a+4,cmp);//数组a按升序排序
for(int i = 0; i<4; i++){
cout << a[i] << " ";
}
return 0;
}
- 利用
functional
标准库,引入头文件#include<functional>
。functional
提供了一些基于模板的比较函数对象。
equal_to<Type>
:等于。not_equal_to<Type>
:不等于。greater<Type>
:大于。greater_equal<Type>
:大于或等于。less<Type>
:小于。less_equal<Type>
:小于或等于。- 升序:
sort(begin,end,less<data-type>())
- 降序:
sort(begin,end,greater<data-type>())
int main(){
int a[4] = {7,4,5,23};
sort(a,a+4,greater<int>());//数组a按升序排序
for(int i = 0; i<4; i++){
cout << a[i] << " ";
}
return 0;
}
nth_element(begin,begin+k,end,compare)
当省略最后一个参数时,该函数使区间[begin,end)
第k
(k
从0开始)小的元素处在第k
个位置上。当最后一个参数为greater<int>()
时,改函数使区间[begin,end)
第k大的元素处在第k个位置上。特别注意:在函数执行后会改变原序列,但不保证其他元素有序。
void print(int a[], int n){
for(int i = 0; i<n; i++){
cout << a[i] << " ";
}
cout << endl;
}
int main(){
int a[7] = {6,2,7,4,20,15,5};
nth_element(a,a+2,a+7);
print(a,7);
int b[7] = {6,2,7,4,20,15,5};
nth_element(b,b+2,b+7,greater<int>());
print(b,7);
return 0;
}
输出:
4 2 5 6 20 15 7 //第2小的数5在第2个位置上
15 20 7 6 4 5 2 //第2大的数7在第2个位置上
lower_bound()/upper_bound()
lower_bound()
和upper_bound()
都是用二分查找的方法在一个有序数组中查找第1个满足条件的元素。
- 在从小到大的排序数组中
lower_bound(begin,end,x)
:从数组的begin
位置到end-1
位置二分查找第1个大于或等于x
的元素,找到后返回该元素的地址,不存在则返回end
。通过返回的地址减去起始地址begin
,得到元素在数组中的下标。upper_bound(begin,end,x)
:从数组的begin
位置到end-1
位置二分查找第1个大于x
的元素,找到后返回该元素的地址,不存在则返回end
。
- 在从大到小的排序数组中
lower_bound(begin,end,x,greater<type>())
:从数组的begin
位置到end-1
位置二分查找第1个小于或等于x
的元素,找到后返回该元素的地址,不存在则返回end
。upper_bound(begin,end,x,greater<type>())
:从数组的begin
位置到end-1
位置二分查找第1个小于x
的元素,找到后返回该元素的地址,不存在则返回end
。
void print(int a[], int n){
for(int i = 0; i<n; i++){
cout << a[i] << " ";
}
cout << endl;
}
int main(){
int a[6] = {6,2,7,4,20,15};
sort(a,a+6);//从小到大排序
print(a,6);
int pos1 = lower_bound(a,a+6,7)-a;//返回数组中第1个大于或等于7的元素下标
int pos2 = upper_bound(a,a+6,7)-a;//返回数组中第1个大于7的元素下标
cout << pos1 << " " << a[pos1] << endl;
cout << pos2 << " " << a[pos2] <<endl;
sort(a,a+6,greater<int>());从大到小排序
print(a,6);
int pos3 = lower_bound(a,a+6,7,greater<int>())-a;//返回第1个小于或等于7的元素下标
int pos4 = upper_bound(a,a+6,7,greater<int>())-a;//返回第1个小于7的元素下标
cout <<pos3 << " "<<a[pos3] <<endl;
cout << pos4 <<" "<<a[pos4] <<endl;
return 0;
}
next_permutation()/pre_permutation()
next_permutation()
是求按字典序排序的下一个排列的函数,可以得到全排列。pre_permutation()
是求按字典序排序的上一个排列的函数。
int
类型的next_permutation()
int main(){
int a[3] = {1,2,3};
do{
for(int i = 0; i<3; i++){
cout << a[i] << " ";
}
cout << endl;
}while(next_permutation(a,a+3));
//如果存在a之后的排列,就返回true
//如果a是最后一个排列且没有后继,则返回false
//每执行一次,a就编程它的后继
return 0;
}
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
如果改成while(next_permutation(a,a+2))
,即只对前2个元素进行字典序排序。输出:
1 2 3
2 1 3
若排列本来就最大,且没有后继,则在next_permutation
执行后,对排列进行字典升序排序,相当于循环。.
int list[3] = {3,2,1};
next_permutation(list,list+3);
cout << list[0] << " " << list[1] << " " << list[2] << " " <<endl;
char
类型的next_permutation()
int main(){
char ch[205];
cin >> ch;
sort(ch,ch+strlen(ch));//该语句对输入的数组进行字典升序排序
//例如输入“9874563102 out << ch;”,则将输出“0123456789”,这样就能输出全排列
char *first= ch
char *last= ch + strlen(ch);
do{
cout << ch <<endl;
}while(next_permutation(first,last));
}
return 0;
char
类型的next_permutation()
int main(){
string s;
while(cin >> s && s!= "#"){
sort(s.begin(),s.end());//全排列
cout << s << endl;
while(next_permutation(s.begin(),s.end())){
cout << s << endl;
}
return 0;
}
}
- 自定义优先级的
next_permutation
int cmp(char a,char b){//A<a<B<b<...<Z<z
if(tolower(a) != tolower(b)){
return tolower(a)<tolower(b);
}
else{
return a<b;
}
}
sort(ch,ch+strlen(ch),cmp);
do{
printf("%s\n",ch);
}while(next_permutation(ch, ch+strlen(ch), cmp))