0
点赞
收藏
分享

微信扫一扫

C++使用技巧(二十六):unique、distance、accumulate搭配lambda函数表达式使用

at小涛 2022-03-20 阅读 100
c++

C++ 11 引入了 lambda 表达式,以允许我们编写一个内联函数,该函数可用于无法重用且不值得命名的短代码片段。最简单的 lambda 表达式可以定义如下:

[ capture clause ] (parameters) -> return-type  
{   
   definition of method   
} 

通常 lambda 表达式中的 return-type 由编译器本身评估,我们不需要显式指定和 -> return-type 部分可以忽略,但在一些复杂的情况下,如条件语句,编译器无法确定返回类型,我们需要指定。

1 capture list 

是一个lambda所在函数中定义的局部变量的列表,通常为空;

2 return type

返回值类型;

可忽略,使用自动推倒;

尾置返回类型;就是用    ->后面跟类型    来表示函数的返回类型,这样更直观;

3 parameter list

参数列表;

可忽略,自动推倒;

4 function body

函数体;

下面给出了具有标准函数的 lambda 表达式的各种用法:

// C++ program to demonstrate lambda expression in C++
#include <bits/stdc++.h>
using namespace std;

// Function to print vector
void printVector(vector<int> v)
{
	// lambda expression to print vector
	for_each(v.begin(), v.end(), [](int i)
	{
		std::cout << i << " ";
	});
	cout << endl;
}

int main()
{
	vector<int> v {4, 1, 3, 7, 2, 3, 1, 17};

	printVector(v);

	// below snippet find first number greater than 4
	// find_if searches for an element for which
	// function(third argument) returns true
	vector<int>:: iterator p = find_if(v.begin(), v.end(), [](int i){return i > 4;});
    //寻找满足以下条件的元素  第一个元素就是输出
	cout << "First number greater than 4 is : " << *p << endl;


	// function to sort vector, lambda expression is for sorting in
	// non-increasing order Compiler can make out return type as
	// bool, but shown here just for explanation
	sort(v.begin(), v.end(), [](const int& a, const int& b) -> bool
	{
		return a > b;//倒顺序 
	});

	printVector(v);

	// function to count numbers greater than or equal to 5
	int count_5 = count_if(v.begin(), v.end(), [](int a)
	{
		return (a >= 5);
	});
	cout << "The number of elements greater than or equal to 5 is : "
		<< count_5 << endl;

	// function for removing duplicate element (after sorting all
	// duplicate comes together)
	p = unique(v.begin(), v.end(), [](int a, int b)
	{
		return a == b;
	});
    
    // printVector(v);
    cout << "去掉重复的数 : "<<endl;

	// resizing vector to make size equal to total different number
	v.resize(distance(v.begin(), p)); //计算去掉后的数组的元素个数,并重新排列大小
	printVector(v);

	// accumulate function accumulate the container on the basis of
	// function provided as third argument
	int arr[] = {1, 2, 3, 4, 5};
	int f = accumulate(arr, arr + 5, 1, [](int i, int j){return i * j;});

	cout << "Factorial of 5 is : " << f << endl;// 将数组的元素相乘,这里类似阶乘计算,如果数字没有顺序就是正常的元素相乘

	//	 We can also access function by storing this into variable
	auto square = [](int i)
	{
		return i * i;
	};

	cout << "Square of 5 is : " << square(5) << endl;
}

执行结果:

4 1 3 7 2 3 1 17 
First number greater than 4 is : 7
17 7 4 3 3 2 1 1 
The number of elements greater than or equal to 5 is : 2
去掉重复的数 : 
17 7 4 3 2 1 
Factorial of 5 is : 720
Square of 5 is : 25

其中:用到的函数
unique的作用是从输入序列中“删除”所有相邻的重复元素。
distance() 函数用于计算两个迭代器表示的范围内包含元素的个数.
accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值。accumulate算法返回累加的结果,其返回类型就是其第三个实参的类型。

这里补充accumulate案例用法:

#include <vector>
#include <numeric>
#include <functional>
#include <iostream>

using namespace std;

int main( ) 
{

   vector <int> v1, v2( 20 );
   vector <int>::iterator Iter1, Iter2;

   int i;
   for ( i = 1 ; i < 21 ; i++ )
   {
      v1.push_back( i );//给向量数组 赋值
   }

   cout << "最初向量v1中个元素的值为:\n ( " ;
   for ( Iter1 = v1.begin( ) ; Iter1 != v1.end( ) ; Iter1++ )
      cout << *Iter1 << " ";
   cout << ")." << endl;

   // accumulate函数的第一个功能,求和
   int total;
   total = accumulate ( v1.begin ( ) , v1.end ( ) , 0 );

   cout << "整数从1到20的和为: " 
        << total << "." << endl;

   // 构造一个前n项和的向量
   int j = 0, partotal;
   for ( Iter1 = v1.begin( ) + 1; Iter1 != v1.end( ) + 1 ; Iter1++ )
   {
      partotal = accumulate ( v1.begin ( ) , Iter1 , 0 );
      v2 [ j ] = partotal;
      j++;
   }

   cout << "前n项和分别为:\n ( " ;
   for ( Iter2 = v2.begin( ) ; Iter2 != v2.end( ) ; Iter2++ )
      cout << *Iter2 << " ";
   cout << ")." << endl << endl;

   // accumulate函数的第二个功能,计算连乘积
   vector <int> v3, v4( 10 );
   vector <int>::iterator Iter3, Iter4;

   int s;
   for ( s = 1 ; s < 11 ; s++ )
   {
      v3.push_back( s );
   }

   cout << "向量v3的初始值分别为:\n ( " ;
   for ( Iter3 = v3.begin( ) ; Iter3 != v3.end( ) ; Iter3++ )
      cout << *Iter3 << " ";
   cout << ")." << endl;

    //相乘,没有遍历
   int ptotal;
   ptotal = accumulate ( v3.begin ( ) , v3.end ( ) , 1 , multiplies<int>( ) );

   cout << "整数1到10的连乘积为: " 
        << ptotal << "." << endl;

   // 构造一个前n项积的向量 相乘,开始遍历
   int k = 0, ppartotal;
   for ( Iter3 = v3.begin( ) + 1; Iter3 != v3.end( ) + 1 ; Iter3++ ) {
      ppartotal = accumulate ( v3.begin ( ) , Iter3 , 1 , multiplies<int>( ) );
      v4 [ k ] = ppartotal;
      k++;
   }

   cout << "前n项积分别为:\n ( " ;
   for ( Iter4 = v4.begin( ) ; Iter4 != v4.end( ) ; Iter4++ )
      cout << *Iter4 << " ";
   cout << ")." << endl;
}

执行结果:

最初向量v1中个元素的值为:
 ( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ).
整数从120的和为: 210.
前n项和分别为:
 ( 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210 ).

向量v3的初始值分别为:
 ( 1 2 3 4 5 6 7 8 9 10 ).
整数110的连乘积为: 3628800.
前n项积分别为:
 ( 1 2 6 24 120 720 5040 40320 362880 3628800 ).

参考

http://www.noobyard.com/article/p-gxpewbej-n.html
https://www.oracle.com/cn/servers/technologies/howto-use-lambda-exp-cpp11.html

举报

相关推荐

0 条评论