函数式编程思想

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

如果对函数式编程思想进行概括,就是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]);elsebreak;}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.rhkb.cn/news/419508.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

camtasia2024破解版本安装包网盘下载 附带永久激活码秘钥

Camtasia 2024 &#x1f31f; 新功能大揭秘&#xff0c;让你轻松成为视频制作达人&#xff01; 嘿&#xff0c;亲爱的小红薯们&#xff01;&#x1f44b; 今天我要给大家介绍一款超实用的视频编辑软件——Camtasia 2024。这款软件可是让我的视频制作技能瞬间提升了不止一个档次…

《数字信号处理》学习05-单位冲击响应与系统响应

目录 一&#xff0c;单位冲激响应 二&#xff0c;LTI系统对任意序列的系统响应 三&#xff0c;LTI系统的性质 通过上一篇文章《数字信号处理》学习04-离散时间系统中的线性时不变系统-CSDN博客的学习&#xff0c;我已经知道了离散时间线性时不变系统&#xff08;LTI&#x…

Linux系统本地化部署Dify并安装Ollama运行llava大语言模型详细教程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Nginx解析:入门笔记

&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 ✨欢迎加入探索nginx之旅✨ &#x1f44b; 大家好&#xff01;文本学习和探索Nginx配置。…

认知杂谈52

今天分享 有人说的一段争议性的话 I I 1拓展人脉很重要** 咱们活在这世上啊&#xff0c;得明白一件事儿&#xff0c;知识、逻辑能力和实战经验虽然重要&#xff0c;但确实都不是最关键的。真正关键的是要懂得怎么和那些手里有资源的人打交道。人脉那可真是一笔无形的大财富呢…

论文解读:《LAMM: Label Alignment for Multi-Modal Prompt Learning》

系列文章目录 文章目录 系列文章目录LAMM: Label Alignment for Multi-Modal Prompt Learning学习1、论文细节理解1、研究背景2、论文贡献3、方法框架4、研究思路5、实验6、限制 LAMM: Label Alignment for Multi-Modal Prompt Learning学习 1、论文细节理解 VL模型和下游任务…

C++ | Leetcode C++题解之第394题字符串解码

题目&#xff1a; 题解&#xff1a; class Solution { public:string src; size_t ptr;int getDigits() {int ret 0;while (ptr < src.size() && isdigit(src[ptr])) {ret ret * 10 src[ptr] - 0;}return ret;}string getString() {if (ptr src.size() || src[…

JS_对象的创建

JS声明对象的语法 通过new Object()直接创建对象 var person new Object(); // 给对象添加属性并赋值 person.name"张明"; person.age10; person.foods["苹果","橘子","香蕉","葡萄"]; // 给对象添加功能函数 person.eat …

数学建模笔记—— 主成分分析(PCA)

数学建模笔记—— 主成分分析 主成分分析1. 基本原理1.1 主成分分析方法1.2 数据降维1.3 主成分分析原理1.4 主成分分析思想 2. PCA的计算步骤3. 典型例题4. 主成分分析说明5. python代码实现 主成分分析 1. 基本原理 在实际问题研究中,多变量问题是经常会遇到的。变量太多,无…

顶层const和底层const

在C中&#xff0c;const修饰符用于声明常量&#xff0c;有两种常见的形式&#xff1a;顶层const和底层const&#xff0c;它们之间的区别在于它们修饰的对象及其在不同场景中的作用。 1. 顶层const (Top-level const) 顶层const用于修饰变量本身&#xff0c;使其成为常量。这意…

Jenkins 通过 Version Number Plugin 自动生成和管理构建的版本号

步骤 1&#xff1a;安装 Version Number Plugin 登录 Jenkins 的管理界面。进入 “Manage Jenkins” -> “Manage Plugins”。在 “Available” 选项卡中搜索 “Version Number Plugin”。选中并安装插件&#xff0c;完成后可能需要重启 Jenkins。 步骤 2&#xff1a;配置…

SQL进阶技巧:每年在校人数统计 | 区间重叠问题

目录 0 问题分析 1 数据准备 2 问题分析 3 小结 区间重叠问题 0 问题分析 有一个录取学生人数表 in_school_stu,记录的是每年录取学生的人数及录取学生的学制,计算每年在校学生人数。 1 数据准备 create table in_school_stu as ( select stack(5,1,2001,2,1200,2,2000…

Sui Narwhal and Tusk 共识协议笔记

一、Overwiew [ 整体流程: Client提交transaction到Narwhal Mempool。(Narwhal Mempool由一组worker和一个primary组成) Mempool接收到的Transaction->以Certificate的形式进行广播 由worker将交易打包为Batch,worker将Batch的hash发送给primary primary上运行了mempo…

关系代数 | 数据库SQL

文章目录 关系运算符笛卡尔积笛卡尔积应用 运算符符号含义集合运算符并∪交∩差-笛卡尔积专门的关系运算符选择σ投影π连接⋈除 关系运算符 笛卡尔积 集合运算符中&#xff0c;主要对笛卡尔积做解释&#xff1a; 在数学中&#xff0c;两个集合X和Y的笛卡儿积&#xff08;英语…

ThreadLocal 释放的方式有哪些

ThreadLocal基础概念&#xff1a;IT-BLOG-CN ThreadLocal是Java中用于在同一个线程中存储和隔离变量的一种机制。通常情况下&#xff0c;我们使用ThreadLocal来存储线程独有的变量&#xff0c;并在任务完成后通过remove方法清理这些变量&#xff0c;以防止内存泄漏。然而&…

使用 WebStorm 导入已有的 Vue 项目并运行的步骤与注意事项

目录 1. 引言2. WebStorm 环境准备2.1 安装 WebStorm2.2 配置 Node.js 和 npm2.3 使用 nvm 管理 Node.js 和 npm 版本2.4 npm 版本与 Vue 版本对应关系 3. 导入已有的 Vue 项目3.1 打开 Vue 项目3.2 安装项目依赖3.3 使用 nvm 控制 Node.js 和 npm 版本 4. 运行 Vue 项目4.1 启…

软件工程-图书管理系统的概要设计

软件概要设计说明书 目录 软件概要设计说明书 一、引言 1.1 编写目的 1.2 背景 1.3 定义 1.3.1特定对象 1.3.2专业术语 1.4 参考资料 二、总体设计 2.1 需求规定 2.1.1信息要求 2.1.2功能要求 2.2 运行环境 2.3 基本概要设计和处理流程 2.4 体系结构设计 2.5 模…

从戴尔公司中国大饭店DTF大会,看科技外企如何在中国市场发展

【科技明说 &#xff5c; 科技热点关注】 2024戴尔科技峰会在8月如期举行&#xff0c;虽然因事未能抵达现场参加&#xff0c;我只是观看了网上在线直播&#xff0c;也未能采访到DTF现场重要与会者&#xff0c;但是通过数十年对戴尔的跟踪与观察&#xff0c;我觉得2024戴尔科技…

基于Java+SpringBoot+Vue+MySQL的美容美发管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于SpringBootVue的美容美发管理系统【附源码文档】、前后…

const、inline、nullptr的使用

目录 1.const引用 1.1权限的放大 1.2权限的缩小 2.inline 3.nullptr 1.const引用 可以引用一个const对象&#xff0c;但是必须用const引用。const引用也可以引用普通对象&#xff0c;因为对象的访问权限在引用过程中可以缩小&#xff0c;但是不能放大。 不需要注意的是类…