zoukankan      html  css  js  c++  java
  • 函数式编程学习总结

    大概了解了一下函数式编程,总的来说可以说,函数式编程就是一种体现函数当成普通变量的思想的编程方法,其中函数指针就是变量,而具体的函数,包括lambda函数就是常量。
    学习过程中的代码如下:

      1 #include <iostream>
      2 #include <vector>
      3 #include <map>
      4 #include <functional>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 //函数式编程的实现:函数指针
      9   //Q:什么是函数指针
     10   //A:函数指针是一种特殊类型的指针变量(指向函数)
     11 
     12   //Q:函数指针是任何函数都可以指向吗
     13   //A:不是,函数指针有类型之分,函数指针的类型会在声明是给出,特定类型的函数指针只能指向特定类型的函数
     14 
     15   //Q:如何声明一个函数指针,或者说不同函数指针的类型怎么区分
     16   //A:eg1:int (*f)(int, int) 其中int(* )(int, int)就是类型, f为函数指针变量
     17   //  eg2:using funType = int (*)(int, int); funType f;
     18 
     19   //Q:为什么没有函数变量
     20   //A:不需要,只需要一个函数就够了,应该工厂只需要一台机器,我们没有必要复制一台功能一模一样的机器
     21 
     22   //总结:函数指针和普通数据类型的指针几乎一致,只是一个指向特定类型的函数(由返回值,参数个数及类型唯一决定), 另一个则指向特定数据类型的变量
     23 /*int main() {
     24     int m_plus(int, int);
     25     //函数指针声明
     26     int(*f)(int, int); //或者:using T = int(*)(int, int); T f;(简单的声明方法) 
     27     //函数指针赋值
     28     f = m_plus;//或者:f = &m_plus(这里是为了可以把函数指针当成一种引用
     29     //函数指针使用
     30     cout << f(1, 2) << endl; //*f不可以(规定吧,没有什么为什么)
     31     system("pause");
     32     return 0;    
     33 }*/
     34 
     35 
     36 
     37 //函数指针的作用
     38 //A1:简化代码
     39 //A2:函数变量化(可以把该指针看成是函数的一种引用), 一个函数指针可以代表该类型下不同的函数, 甚至可以作为函数参数, 使得函数功能具有范式的特点
     40 /*int main() {
     41 #if 0
     42 //例子1:给出3个int型整数a、b、c,当c=0时,求a+b, 当c=1时,求a-b, 当c=2时,求a*b, 当c=3时, 求a/b
     43     int m_plus(int, int);
     44     int m_minus(int, int);
     45     int m_multiply(int, int);
     46     int m_devide(int, int);
     47     int a, b, c;
     48     cin >> a >> b >> c;
     49     using funType = int(*)(int, int);
     50     map<int, funType> m = { {0, &m_plus}, {1, m_minus}, {2, m_multiply}, {3, m_devide} };//加不加引号都可以
     51     cout << m[c](a, b);
     52     system("pause");
     53     return 0;
     54 #else
     55 //例子2:实现f(g(x) = 2(g(x))的效果
     56     int f(int, int(*)(int));
     57     int g1(int);
     58     int g2(int);
     59     int g3(int);
     60     int x;
     61     cout << "输入x:";
     62     cin >> x;
     63     cout << "f(2*x) = " << f(x, g1) << endl;
     64     cout << "f(2*x^2) = " << f(x, g2) << endl;
     65     cout << "f(2*x^3) = " << f(x, g3) << endl;
     66     system("pause");
     67     return 0;
     68 #endif
     69 }*/
     70 
     71 
     72 
     73 
     74 //lambda表达式
     75 //Q:lambda表达式有什么用
     76 //A1:实现了函数的数值化,可以把一个lambda表达式看成一个数值(该表达式会返回一个函数指针)
     77 //A2:与函数指针配合实现了数据类型定义变量的效果(int x = 0)
     78 //A3:返回一个函数
     79 /*int main() {
     80 #define SEL 5
     81 #if (SEL == 1)
     82     //例子1:用lambda表达式实现a%b函数
     83     auto f = [](int a, int b) { return a % b; };
     84     int a, b;
     85     cin >> a >> b; 
     86     cout << f(a, b);
     87     system("pause");
     88     return 0;
     89 #elif (SEL == 2)
     90     //例子2:给出3个int型整数a、b、c,当c=0时,求a+b, 当c=1时,求a-b, 当c=2时,求a*b, 当c=3时, 求a/b
     91     map<int, int(*)(int, int)> m = {
     92         {0,[](int a, int b) {return a + b;}},
     93         {1,[](int a, int b) {return a - b;}},
     94         {2,[](int a, int b) {return a * b;}},
     95         { 3,[](int a, int b) {return a / b;}}
     96     };
     97     int a, b, c;
     98     cin >> a >> b >> c;
     99     cout << m[c](a, b);
    100     system("pause");
    101 #elif(SEL == 3)
    102     //例子3:假设不使用map,仍使用if-else的语句,你能通过传递lambda表达式作函数参数的形式,在main函数外,仅实现一个函数compute来实现加减乘除求余这5种运算吗?
    103     int compute(int(*)(int, int), int, int);
    104     int a, b, c;
    105     cin >> a >> b >> c;
    106     if (c == 0)
    107         cout << compute([](int a, int b) {return a + b; }, a, b);
    108     else if (c == 1)
    109         cout << compute([](int a, int b) {return a - b; }, a, b);
    110     else if (c == 2)
    111         cout << compute([](int a, int b) {return a * b;}, a, b);
    112     else
    113         cout << compute([](int a, int b) {return a / b;}, a, b);
    114     system("pause");
    115     return 0;
    116 #elif(SEL == 4)
    117     //例子4:返回一个函数
    118     function<int(int, int)>g();
    119     auto i = g();
    120     cout << i(1, 2);
    121     system("pause");
    122     return 0;
    123 #endif
    124 }*/
    125 
    126 function<int(int, int)>g() {
    127     return [](int a, int b) {return a + b; };
    128 }
    129 
    130 //函数指针的更好替代:function标准库类型
    131 /*int main() {
    132     function<int(int, int)> f = [](int a, int b) {return a + b;};
    133     cout << f(1, 2) << endl;
    134     system("pause");
    135     return 0;
    136 }*/
    137 
    138 //functional库中的其他函数(function好比变量, 其他函数好比常量)
    139 /*int main() {
    140 #define SEL 3
    141 #if (SEL == 1)
    142     //例子1:
    143     auto i = plus<int>();
    144     cout << i(1, 2) << endl;
    145     cout << minus<int>()(2, 1) << endl;
    146     cout << divides<double>()(2.5, 2) << endl;
    147     cout << modulus<int>() (8, 3) << endl;
    148     cout << negate<int>()(3) << endl;
    149     cout << equal_to<int>()(2, 2) << endl;
    150     cout << not_equal_to<int>()(2, 3) << endl;
    151     cout << greater<int>()(3, 2) << endl;
    152     cout << greater_equal<int>()(3, 2) << endl;
    153     cout << less<double>()(3.2, 4.5) << endl;
    154     cout << less_equal<int>()(3, 2) << endl;
    155     cout << logical_and<int>()(3, 2) << endl;
    156     cout << logical_or<int>()(3, 2) << endl;
    157     cout << logical_not<int>()(3) << endl;
    158     system("pause");
    159     return 0;
    160 #elif (SEL == 2)
    161     //例子2:
    162     map<int, function<int(int, int)>> m = {
    163         {0, plus<int>()}, {1, minus<int>()},
    164         {2, multiplies<int>()}, {3, divides<int>()}
    165     };
    166     int a, b, c;
    167     cin >> a >> b >> c;
    168     cout << m[c](a, b);
    169     system("pause");
    170     return 0;
    171 #elif (SEL == 3)
    172     //例子3:排序的应用
    173     vector<int> v = { 2, 5, 4, 1, 3 };
    174     sort(v.begin(), v.end(), greater<int>());
    175     for (int i : v)
    176         cout << i << " ";
    177     system("pause");
    178     return 0;
    179 #endif
    180 }*/
    181 
    182 //练习
    183 double compute1(double a, double b, function<double(double)> f) {
    184     return (f(b) + f(a)) * (b - a) / 2;
    185 }
    186 double fun1(double k, double m, double x) {  //1次函数
    187     return k * x + m;
    188 }
    189 function<double(double)>fun1ForApplication(int k, int m) {  //返回或者产生具体的一次函数(k, m确定)
    190     return [k, m](double x) {return fun1(k, m, x);};//捕获,相当于把
    191 }
    192 int main() {
    193 #define SEL 2
    194 #if (SEL == 1)
    195     //练习1:求一次函数的积分
    196     cout << "2x + 10 在 (3, 7) 范围内的积分为:";
    197     cout << compute1(3, 7, [](double x) { return 2 * x + 10; });
    198 #elif (SEL == 2)
    199     //练习2:用科里化的方式对上述练习进行改进(捕获)
    200     auto i = fun1ForApplication(2, 10);  //i 为 2 * x + 10 的函数
    201     cout << compute1(3, 7, i) << endl;
    202 #endif
    203     system("pause");
    204     return 0;
    205 }
    206 
    207 int m_plus(int a, int b) {
    208     return a + b;
    209 }
    210 int m_minus(int a, int b) {
    211     return a - b;
    212 }
    213 int m_multiply(int a, int b) {
    214     return a * b;
    215 }
    216 int m_devide(int a, int b) {
    217     return a / b;
    218 }
    219 int f(int x, int(*g)(int)) {
    220     return 2 * g(x);
    221 }
    222 int g1(int x) {
    223     return x;
    224 }
    225 int g2(int x) {
    226     return x * x;
    227 }
    228 int g3(int x) {
    229     return x * x * x;
    230 }
    231 int compute(int(*f)(int, int), int a, int b) { //f为二元运算函数
    232     return f(a, b);
    233 }
  • 相关阅读:
    [图解]在输入框和文本框中获取和设置光标位置,以及选中文本和获取选中文本值的方法 --- 详解,兼容所有浏览器。
    关于鼠标事件的screenY,pageY,clientY,layerY,offsetY属性 (详细图解)
    get新技能: 如何设置元素高度与宽度成特定比例。宽度改变,高度自动按比例改变。 例如设置宽高比16:9。
    jQuery源码 Ajax模块分析
    jQuery 1.9 Ajax代码带注释
    html5 自定义数据属性 ,也就是 data-* 自定义属性---笔记。
    client/scroll/offset width/height/top/left ---记第一篇博客
    JSON对象长度和遍历方法
    如何组织css,写出高质量的css代码
    css中文本框与按钮对不齐解决方案
  • 原文地址:https://www.cnblogs.com/Serenaxy/p/11881090.html
Copyright © 2011-2022 走看看