函数式编程思想

news2024/9/17 7:09:12

我们经常会用到各种各样的编程思想,例如面向过程、面向对象。不过笔者在该博客简单介绍一下函数式编程思想.

如果对函数式编程思想进行概括,就是f(x) = na(x) , y=uf(x)…至于其他的编程思想,可能是y=a(x)+b(x)+c(x)…,也有可能是y=f(x)=f(x)/a + f(x)/b+f(x)/c…

面向过程的指令式编程

面向过程,简单理解就是y=a(x)+b(x)+c(x)…这种,可能有人会问面向对象,嗯,对于这种小型精巧的分治算法,使用面向对象有点像是无稽之谈,所以指令式的面向过程往往是一个好选择。

下面以快速排序为例,现在我们需要对数组进行从小到大排序。

快速排序的核心就是:将数组划分为左右两个子集,保证右边的元素比左边大,然后不断递归重复这个过程。

我们要实现排序的过程如下:

分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
全集
左子集
右子集
左子集的左子集
左左左子集
左左右子集
左子集的右子集
左右左子集
左右右子集
右子集的左子集
右左左子集
右左右子集
右子集的右子集
右右左子集
右右右子集

显然,这是一个不断递归的过程,但是我们可以观察到,程序总是在重复分割交换这个过程,因此将交换和分割单独写一个函数,作为基本指令。因此我们需要有三个函数:交换函数、分区函数、排序函数。

过程如下:

#include <stdio.h>

// 交换两个元素
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 分区函数
int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // 选择最后一个元素作为枢轴
    int i = (low - 1); 

    for (int j = low; j <= high - 1; j++) {
        // 如果当前元素小于或等于枢轴
        if (arr[j] <= pivot) {
            i++; //j查找比枢纽小的元素,i++后必然指向比枢纽大的元素,否则i与j会同步更新
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    return (i + 1);
}


/*
//笔者更喜欢使用下面这种,分析源码就可以知道,下面更接近二分查找的形式,而上面更接近从头遍历。
//经过笔者测试,上面的平均耗时几乎是下面的1.7倍

int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // 选择最后一个元素作为枢轴
    int i = low - 1; // 较小元素的索引
    int j = high ;
    for( ; ; )
    {
        while( arr[++i] < pivot){ }
        while( arr[--j] > pivot && j > low){ }
        if( i < j)
            swap(&arr[i],&arr[j]);
        else
            break;
    }
    swap(&arr[i], &arr[high]);
    return i ;
}

 */



// 快速排序函数
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        // pi 是分区索引,arr[pi] 已经排好序
        int pi = partition(arr, low, high);

        // 分别排序两个子数组
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

// 打印数组
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int main() {
    int arr[] = {10, 7, 8, 9, 1, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    quickSort(arr, 0, n - 1);
    printf("Sorted array: \n");
    printArray(arr, n);
    return 0;
}

现在让我们来看看函数式编程:

函数式编程

函数式编程的重点在于数组,简单用该图理解:

简单来说就是,重点关心输入和输出,屏蔽其他因素。

图中的过程是,输入全集数组,输出结果是无数个小数组,输入小数组,输出结果是合并后的全集数组。所以我们需要有两个函数:排序分割函数、合并函数。

分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
分割与交换
合并
合并
合并
合并
合并
合并
合并
合并
全集
左左左子集
左左右子集
左右左子集
左右右子集
右左左子集
右左右子集
右右左子集
右右右子集
排序后的数组

代码如下:

#include <stdio.h>
#include <stdlib.h>

//排序的本质是对数组的操作,它将数组划分为一个个的小单元
typedef struct {
    int* array;
    int length;
} SubArray;

//合并小单元
SubArray concatenate(SubArray left, int pivot, SubArray right) {
    int* new_array = (int*)malloc((left.length + right.length + 1) * sizeof(int));
    for (int i = 0; i < left.length; i++) {
        new_array[i] = left.array[i];
    }
    new_array[left.length] = pivot;
    for (int i = 0; i < right.length; i++) {
        new_array[left.length + 1 + i] = right.array[i];
    }
    return (SubArray){new_array, left.length + right.length + 1};
}


SubArray quicksort(int* array, int length) {
    if (length <= 1) {
        return (SubArray){array, length};
    }

    int pivot = array[0];

    int* left_array = (int*)malloc(length * sizeof(int));
    int* right_array = (int*)malloc(length * sizeof(int));
    int left_size = 0, right_size = 0;

    for (int i = 1; i < length; i++) {
        if (array[i] <= pivot) {
            left_array[left_size++] = array[i];
        } else {
            right_array[right_size++] = array[i];
        }
    }

    SubArray left_sorted = quicksort(left_array, left_size);
    SubArray right_sorted = quicksort(right_array, right_size);

    SubArray result = concatenate(left_sorted, pivot, right_sorted);

    free(left_sorted.array);
    free(right_sorted.array);

    return result;
}

void printArray(int* array, int length) {
    for (int i = 0; i < length; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
}

int main() {
    int array[] = {10, 7, 8, 9, 1, 5};
    int length = sizeof(array) / sizeof(array[0]);

    SubArray sorted = quicksort(array, length);

    printf("Sorted array: ");
    printArray(sorted.array, sorted.length);
    free(sorted.array);

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在Linux下查看HBA卡的速率和状态

平时在Linux下映射存储&#xff0c;都是映射哪台就给哪台插线&#xff0c;然后在存储端扫描WWPN&#xff0c;简单粗暴&#xff0c;没技术含量。当然&#xff0c;光交下也可以看。 1&#xff0c;查看当前卡的品牌&#xff0c;常用的卡有两种&#xff0c;Emulex和Qlogic。 lspc…

C语言 - 预处理详解(一)#预定义符号 ##define #undef

文章目录 前言 一、预定义符号 二、#define (一)、#define 定义的标识符 (二)、#define 定义的宏 (三)、#define 替换规则 (四)、# 和 ## 1、 # 的作用 2、## 的作用 (五)、带副作用的宏参数 (六)、宏和函数的对比 (七)、命名约定 三、#undef 总结 前言 路漫漫其修远兮&#…

C语言深度剖析--不定期更新的第五弹

const关键字 来看一段代码&#xff1a; #include <stdio.h> int main() {int a 10;a 20;printf("%d\n", a);return 0; }运行结果如下&#xff1a; 接下来我们在上面的代码做小小的修改&#xff1a; #include <stdio.h> int main() {const int a 1…

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口 int main(int argc, char *argv[]) {//…

IDA的安装和使用

IDA Pro&#xff08;简称 IDA&#xff0c;官网地址为 https://www.hex-rays.com/products/ida/&#xff09;是一个反编译器&#xff0c;同时具备调试器的功能。IDA Pro 的功能非常强大&#xff0c;几乎所有的逆向题目都需要用到它&#xff0c;因而也被称为「逆向神器」 IDA安装…

MySQL入门到精通

一、创建数据库 CREATE DATABASE 数据库名称; 如果数据库存在&#xff0c;则会提示报错。 二、选择数据库 USE 数据库名称; 三、创建数据表 CREATE TABLE 数据表名称; 四、MySQL数据类型 MySQL支持多种类型&#xff0c;大致可以分为三类&#xff1a;数值、日期/时间和字符串…

Data Filtering Network论文浅析

time2023-09paperhttps://arxiv.org/abs/2309.17425codehttps://huggingface.co/apple/DFN5B-CLIP-ViT-H-14-378org.Apple个人博客地址http://myhz0606.com/article/dfn Motivation 训练一个好的CLIP模型依赖大规模&#xff0c;高质量的训练数据。通过爬虫&#xff0c;可以很…

S7-1200与G120变频器CU240E-2控制单元通过353报文实现PN通信的基本方法

S7-1200与G120变频器CU240E-2控制单元通过353报文实现PN通信的基本方法 西门子报文353 PKW+PZD-2/2, 6个字中前4个字是PKW用,后2个字是PZD用, 结合以上内容, 可以知道第5个字是STW1控制字,第6个字是转速给定值(PLC输出);第5个字是ZSW1是状态字,第6个字是当前转速值(P…

LeetCode:快乐数(202)

目录 题目 代码思路 双指针 代码实现 题目 202. 快乐数 - 力扣&#xff08;LeetCode&#xff09; 编写一个算法来判断一个数 n 是不是快乐数。 [ 快乐数 ] 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程…

ThinkPHP5 5.0.23-rce远程代码执行漏洞复现

漏洞描述 ThinkPHP是一款运用极广的PHP开发框架。其版本5中&#xff0c;由于框架对控制器名没有进行足够的检测&#xff0c;会导致在没有开启强制路由的情况下可执行任意方法&#xff0c;从而导致远程命令执行漏洞。 启动容器 docker-compose up -d 查看端口 docker ps 端口为…

【C++进阶】hash表的封装

文章目录 hash表哈希表的关键组成部分哈希表的优缺点优点&#xff1a;缺点&#xff1a; 常见应用场景 开放定址法实现hash表负载因子 (Load Factor)负载因子的意义负载因子的影响再散列 (Rehashing)示例 整体框架insertFinderasehash桶封装框架insertfinderase~HashTable() 总结…

从路径优化学习FastPlanner之B样条曲线平滑(二):FastPlanner中B样条曲线代码理解与解读

参考别人的博客学习 根据之前一章只是大致了解了B样条数学原理&#xff0c;实际读代码还有疑惑。 控制点是什么&#xff1f;和规划出的路径点什么关系&#xff1f; 控制点可以说我们规划出的路径点&#xff0c;即n等于轨迹点个数。也可以不是轨迹点&#xff0c;通过线性方程反解…

Einsum(Einstein summation convention)

Einsum&#xff08;Einstein summation convention&#xff09; 笔记来源&#xff1a; Permute和Reshape嫌麻烦&#xff1f;einsum来帮忙&#xff01; The Einstein summation convention is a notational shorthand used in tensor calculus, particularly in the fields of …

免费也能高质量!2024年免费录屏软件深度对比评测

我公司因为客户覆盖面广的原因经常会开远程会议&#xff0c;有时候说的内容比较广需要引用多份的数据&#xff0c;我记录起来有一定难度&#xff0c;所以一般都用录屏工具来记录会议内容。这次我们来一起探索有什么免费录屏工具可以提高我们的工作效率吧。 1.福晰录屏大师 链…

9.7(QT.Day 1)

一、自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 要求&#xff1a;每行代码都有注释 【需要用到的图片或者动图&#xff0c;自己去网上找】 1.mywidget.h代码 #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include <QIcon> //图…

C++之格式化日期时间为字符串(精确到毫秒)

C11中提供了获取时间的chrono库&#xff0c;但是格式化显示太方便&#xff1b;C11还提供了格式化时间iomanip库&#xff0c;通过其put_time方法可以格式化时间到秒&#xff0c;要显示毫秒&#xff0c;就需要自己处理了。 #include <chrono> #include <string> #in…

css flex与inline-flex的区别

1、flex与inline-flex布局&#xff0c;都是弹性布局&#xff0c;盒状容器布局。 Flex 布局是什么&#xff1f;_w3cschool 2、下面一个实例来说明一下&#xff1a; 有一个要求&#xff0c;要求item增多的时候&#xff0c;不会换行&#xff0c;并且container容器也会随时item的…

【机器学习】我小学二年级妹妹都能理解的线性回归算法

什么是线性回归&#xff1f; 我小学二年级的妹妹想用压岁钱买房子&#xff0c;售楼广告上写着100万可以买100的房子&#xff0c;200万可以买200的房子&#xff0c;但是我的妹妹觉得那些房子都太小了&#xff0c;想买300的房子&#xff0c;那她应该要花多少钱呢&#xff1f; 对…

DBMS-2.2 数据库设计(2)——数据库规范化设计理论

本文章的素材与知识来自李国良老师和冠宇老师。 依赖理论 对于关系数据库中的依赖&#xff0c;分为函数依赖、多值依赖和连接依赖。 一.函数依赖 1.函数依赖 &#xff08;1&#xff09;定义&#xff1a; &#xff08;2&#xff09;理解&#xff1a; 通俗地讲&#xff0c;…

【Linux】借命令行参数的引导,探索环境变量的奥秘

目录 1.命令行参数 1.1.概念&#xff1a; 1.2.利用命令行参数打造计算器&#xff1a; 2.环境变量 2.1.环境变量是什么&#xff1f; 2.2.有什么方法可以不用带路径&#xff0c;直接就可以运行自己的程序呢&#xff1f; 法一&#xff1a; 法二&#xff1a; 2.3.通过代码…