algorithm头文件常用函数

algorithm意为"算法",是C++的标准模版库(STL)中最重要的头文件之一,提供了大量基于迭代器的非成员模板函数。

  • 类 别 C++标准库
  • 头文件 #include <algorithm>
  • 命名空间 using namespace std

其中包括以下部分函数:

  1. max()、min()和abs()
  2. swap()
  3. reverse()
  4. next_permutation()
  5. fill()
  6. sort()
  7. lower_bound()和upper_bound()
  • 最大最小操作
max 返回两个元素中值最大的元素
min 返回两个元素中值最小的元素
abs() 返回元素绝对值
next_permutation 返回给定范围中的元素组成的下一个按字典序的排列
  • 修改内容操作
swap 交换两个对象的值
reverse 反转排序指定范围中的元素
fill 将一个范围的元素赋值为给定值
  • 排序操作
sort 排序
  • 查找操作
lower_bound 返回指向范围中第一个值大于或等于给定值的元素的迭代器
upper_bound 返回指向范围中第一个值大于给定值的元素的迭代器
  • max()

作 用:返回一个最大数值
语 法:MAX(number1,number2,…)
参 数: Number1,number2,

注意: 如果参数不包含数字,函数 MAX 返回 0。

示例
示例1:如果 A1:A5 包含数字 10、7、9、27 和 2,则:
MAX(A1:A5) 等于 27
MAX(A1:A5,30) 等于 30

示例2:如果A1=71、A2=83、A3=76、A4=49、A5=92、A6=88、A7=96。
则公式“=MAX(A1:A7)”返回96。

#include <iostream>    
#include <algorithm>    
using namespace std;
int main () {
  cout << "max(1,2)==" << std::max(1,2) << '\n';
  cout << "max(2,1)==" << std::max(2,1) << '\n';
  cout << "max('a','z')==" << std::max('a','z') << '\n';
  cout << "max(3.14,2.73)==" << std::max(3.14,2.73) << '\n';
  return 0;
}

在这里插入图片描述

  • min()

min(x,y)分别返回x和y中的最小值,且参数必须是两个。

示例1:如果 A1:A5 中依次包含数值 10,7,3,27 和 2,那么
MIN(A1:A5) 等于 2
MIN(A1:A5, 0) 等于 0

例:

#include <iostream>     
#include <algorithm>    
using namespace std;
int main () {
  cout << "min(1,2)==" << min(1,2) << '\n';
  cout << "min(2,1)==" << min(2,1) << '\n';
  cout << "min('a','z')==" << min('a','z') << '\n';
  cout << "min(3.14,2.72)==" << min(3.14,2.72) << '\n';
  return 0;
}

在这里插入图片描述

  • abs()

abs(x) 返回x的绝对值。x必须为整数,浮点型的绝对值要用math头文件下的fabs

//#include<algorithm>
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int main()
{
    int x,f;
 
	printf("请输入一个整数:\n");
	scanf("%d",&x);
	printf("绝对值为%d\n",abs(x));

//	printf("请输入一个浮点数:\n");
//	scanf("%lf",&f);
//	printf("绝对值为%lf\n",fabs(f));
	return 0;
}

如果没有头文件,绝对值返回0
在这里插入图片描述

  • swap()
    交换两个对象的值,即交换a和b的值。

通用的函数交换模板
template<class T> void swap(T &a,T &b) { T c(a); a=b; b=c; }
针对int类型的优化

void swap(int &a,int &b)
 {
     a^=b;
     b^=a;       //相当于b=a
    a^=b;       //相当于a=b
 }

自定义swap时,注意事项
1.无法实现交换目的

void swap(int a,int b)//这里只是交换了a和b实参的副本,而它们本身没有交换。
 {
     int temp=a;
    a=b;
   b=temp;
 }

2.能够达到交换目的

#include <iostream>    
#include <algorithm>   
 
using namespace std;
void swap(int *a,int *b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}

//使用
int main()
{
    int a=1,b=2;
    swap(&a,&b);
  cout<<a<<endl;
  cout<<=<<endl;
    return 0;
}

在这里插入图片描述

  • reverse()

1.会将区间内的元素全部逆序。常用于数组,字符串,容器等,其本身的函数参数也不复杂。
2.容器类型的要用begin()和end()来指定反转的区域,数组类型的直接用int类型即可。
3.reverse函数用于反转在[first,last)范围内的顺序(包括first指向的元素,不包括last指向的元素),reverse函数没有返回值

此函数模板的行为等效于(通过调用iter_swap来交换元素位置):

template <class BidirectionalIterator>
  void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
  while ((first!=last)&&(first!=--last)) {
    std::iter_swap (first,last);
    ++first;
  }
}
  • 交换vector容器中元素的顺序
vector<int> v = {5,4,3,2,1};
reverse(v.begin(),v.end());//v的值为1,2,3,4,5
  • string类的字符串
string str="www.mathor.top";
reverse(str.begin(),str.end());//str结果为pot.rohtam.wwww

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int a[50];
	int b[50]; 
	for(int i=0;i<10;i++)
	{
		a[i]=i;
		if(i!=9)
		cout<<a[i]<<" ";
		else
		cout<<a[i]<<endl;
	}
	reverse(a,a+10);         //第二个参数是数组最后一个元素的下一个地址 
	for(int i=0;i<10;i++)
	{
		if(i!=9)
		cout<<a[i]<<" ";
		else
		cout<<a[i]<<endl;
	}
}

在这里插入图片描述

  • next_permutation()

返回给定范围中的元素组成的下一个按字典序的排列,next_permutation(start,end)和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列。

next_permutation函数,其函数原型为:

   #include <algorithm>

     bool next_permutation(iterator start,iterator end)//当当前序列不存在下一个排列时,函数返回false,否则返回true
  • 当把while(next_permutation(num,num+3))中的3改为2时,输出就变为了:只对1,2进行全排,可以知道next_permutation(num,num+n)函数是对数组num中的前n个元素进行全排列,同时并改变num数组的值。
    在这里插入图片描述
  • 还有next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。比如,如果数组num初始化为2,3,1,那么输出就变为了:
    在这里插入图片描述
  • 此外,next_permutation(node,node+n,cmp)可以对结构体num按照自定义的排序方式cmp进行排序。也可以对字符next_permutation 自定义比较函数

  • 若排列本米就是最大的了没有后继,则next permotation执行后,会对
    排列进行字典开序排序相当于循环
int list[31={3.,2.1};
next permutation(list,list+3);
conut<<list[0]<<" "<list[U<<" "<listl2k<<endl;//输出:1 2 3

  • List item

char类型的next permutation

//
该语句对输入的数组进行字典升序排序如输入9874563102 cout<<ch;
将输出 0123456789这样就能输出全排列了

int mainO
char ch[2051;cin>> ch;
sort(ch, ch+ strlen(ch));
//这样就不必事先知道ch的大小了,是把整个ch字符串全都进行排序
//若采用while(nextpermutation(ch,ch+5);如果只输入1562,就会产
生错误,因为ch中第五个元素指向未知
//若要整个字符中进行排序,参数5指的是数组的长度,不含结束符

char *frstE ch;
char *last ch+ strlen(ch);
do{
cout<<ch<< endl;
}while(next permutation(first,lastD);return0;
  • string类型的nextpermutation
int main()
{
	string line;
	while(cin>>line&&line!="#"')
	{
		if(nexL permutation(line.beginQline.end0)当前输入位置开始
		cout<line<<endl;
		elsecout<< "Nosuccesor\";
	}
}
int main()
{
	string line;
	while(cin> >line&line!= "#")
	{
		sort(line.begin(),line.end0);/排列cout< dline<<endl;
	}
}


    #include <iostream>  
    #include <algorithm>  
    using namespace std;  
    int main()  
    {  
        int num[3]={1,2,3};  
        do  
        {  
            cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;  
        }
        while(next_permutation(num,num+3));  
        return 0;  
    }  

在这里插入图片描述

  • fill()

1.按照单元赋值,将一个区间的元素都赋同一个值
2.fill(arr, arr + n, 要填入的内容);
fill(vector.begin(), vector.end(), val);
3.

#include <cstdio>
#include <algorithm>
using namespace std;
int main() {
    int arr[10];
    fill(arr, arr + 10, 2);
    return 0;
}

4.vector容器

#include <algorithm>
 #include <vector> 
 #include <iostream> 
 using namespace std; 
 int main()
 { 
	 vector<int>  v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	  fill(v.begin(), v.end(), -1);
	   return 0; 
   } 

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main () {
	vector<int> myvector (8);// myvector: 0 0 0 0 0 0 0 0
	fill (myvector.begin(),myvector.begin()+4,5);
	// myvector: 5 5 5 5 0 0 0 0
	fill (myvector.begin()+3,myvector.end()-2,8);
	// myvector: 5 5 5 8 8 8 0 0
	
	cout << "myvector contains:";
	for (vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
	cout << " " << *it;
	
	cout << endl;
	return 0;
}

在这里插入图片描述

  • sort()

1.Sort函数有三个参数:
(1)第一个是要排序的数组的起始地址。
(2)第二个是结束的地址(最后一位要排序的地址的下一地址)
(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。
2.Sort函数使用模板:Sort(start,end,排序方法)

//例一:sort函数没有第三个参数,实现的是从小到大
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int a[10]={9,6,3,8,5,2,7,4,1,0};
	for(int i=0;i<10;i++)
	cout<<a[i]<<endl;
	sort(a,a+10);
	for(int i=0;i<10;i++)
	cout<<a[i]<<endl;
	return 0;
}
//例2需要在sort()函数里的第三个参数里,从大到小排序!
//加入一个比较函数compare(),
#include<iostream>
#include<algorithm>
using namespace std;
bool compare(int a,int b)
{
return a>b;
}
int main()
{
int a[10]={9,6,3,8,5,2,7,4,1,0};
for(int i=0;i<10;i++)
cout<<a[i]<<endl;
sort(a,a+10,compare);//在这里就不需要对compare函数传入参数了,
//这是规则
for(int i=0;i<10;i++)
cout<<a[i]<<endl;
return 0;
}

  • lower_bound()和upper_bound( )

lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。

、lower_bound()

  • lower_bound()返回值是一个迭代器,返回指向比key大的第一个值的位置
    对象:有序数组或容器
  • lower_bound(起始地址,结束地址,要查找的数值) 返回的是数值 第一个 出现的位置。
  • 功能:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置.

注意:如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!

二、upper_bound()

  • upper_bound(起始地址,结束地址,要查找的数值) 返回的是数值 最后一个 出现的位置。
  • 功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置

注意:返回查找元素的最后一个可安插位置,也就是“元素值>查找值”的第一个元素的位置。同样,如果val大于数组中全部元素,返回的是last。(注意:数组下标越界)

 #include <iostream>  
    #include <algorithm>  
    #include<vector>
    using namespace std; 
int main()
{
    vector<int> t;
    t.push_back(1);
    t.push_back(2);
    t.push_back(3);
    t.push_back(4);
    t.push_back(6);
    t.push_back(7);
    t.push_back(8);

    
    int low=lower_bound(t.begin(),t.end(),5)-t.begin();
    int upp=upper_bound(t.begin(),t.end(),5)-t.begin();
    cout<<low<<endl;
    cout<<upp<<endl;

    
    
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zm_960810/article/details/86249861