热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

处理大数相加的函数式方法与技巧

在处理大数相加的问题时,有许多方法可以借鉴。本文介绍了两种不同的函数式编程方法:一种是从网络上找到的经典实现,另一种是作者自行设计的创新方案。通过函数式编程的方式重新实现了这两种方法,其中经典实现简洁明了,而创新方案则在性能和可读性方面有所提升。这些方法不仅适用于大数相加,还可以扩展应用于其他数值计算场景。

處理大數相加的要領有許多,網上很輕易搜到,下面引見兩種,一種是在網上抄的,一種是本身想的,我將他們都用函數式的體式格局重寫了一遍。

這類是在網上抄的,確實異常簡約

function add(a,b) {
let res='', c=0;
a = a.split('');
b = b.split('');
while (a.length || b.length || c){
c += ~~a.pop() + ~~b.pop();
res = c % 10 + res;
c = c>9;
}
return res.replace(/^0+/,'');
}

函數式重寫,重點在尾遞歸,這是在函數式編程中替代while的寫法。

let compose = (f, g) => (...args) => f(g(...args));
let addUnit = a => b => b + a;
let myPop = a => a.pop(); // 有副作用
let myNumber = a => ~~a;
let remainderTen = x => x % 10;
let isGreeterNine = x => x > 9;
let replaceHeadZero = x => x.replace(/^0+/, "");
let pAndN = compose(myNumber, myPop);
let loop = (a, b, res, c) => { //尾遞歸,即在函數末端自挪用
if (!a.length && !b.length && !c) return res;
let getC = compose(addUnit(pAndN(b)), addUnit(pAndN(a)));
let getEes = compose(addUnit(res), remainderTen);
return loop(a, b, getEes(getC(c)), isGreeterNine(getC(c)));
}
let add = (a, b) => compose(replaceHeadZero, loop)(a.split(""), b.split(""), "", 0);

本身想的

運用累加器完成

function add(a, b) {
a = a.split('').reverse();
b = b.split('').reverse();
function addMap(aArrayIns, bArrayIns) {
return aArrayIns.reduce((accumulator, currentValue, index) => {
let c = ~~bArrayIns[index] + ~~currentValue + ~~accumulator[index];
if (c >= 10) {
accumulator[index] = (c - 10).toString();
accumulator.push('1');
} else {
accumulator[index] = c.toString();
}
return accumulator;
}, []).reverse().join('');
}
return a.length >= b.length ? addMap(a, b) : addMap(b, a);
}

函數式重寫

let compose = (f, g) => x => f(g(x));
let myReverse = x => {
let [...y] = x;
return y.reverse();
};
let mySplit = x => x.split("");
let myToString = x => x.toString();
let myPushOne= x => {
let [...y] = x;
y.push("1");
return y;
}
let setValue = index => value => targetArray => {
let [...y] = targetArray;
y[index] = value;
return y;
}
let splitAndReverse = compose(myReverse, mySplit);
let myReduce = x => y => y.reduce(fnHandleAdd(splitAndReverse(x)), []);
let fnHandleAdd = a => (accumulator, currentValue, index) => {
let c = ~~a[index] + ~~currentValue + ~~accumulator[index];
return c >= 10
? compose(myPushOne, setValue(index)(myToString(c - 10)))(accumulator)
: setValue(index)(myToString(c))(accumulator);
};
let addMap = (a, b) => compose(compose(R.join(""), myReverse), compose(myReduce(b), splitAndReverse))(a);
let add = (a, b) => a.length >= b.length ? addMap(a, b) : addMap(b, a);

下面這類寫法,很不文雅

let addMap = (a, b) => compose(compose(R.join(""), myReverse), compose(myReduce(b), splitAndReverse))(a);

最好compose能夠完成組合恣意個函數,結果以下

let addMap = (a, b) => compose(R.join(""), myReverse, myReduce(b), splitAndReverse)(a);

完成思緒在:https://github.com/zhuanyongx…

我在github https://github.com/zhuanyongx…


推荐阅读
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
author-avatar
hedongsheng
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有