两个函数式解决大数相加的方法
发布时间:2020-12-14 04:49:40 所属栏目:大数据 来源:网络整理
导读:解决大数相加的方法有很多,网上很容易搜到,下面介绍两种,一种是在网上抄的,一种是自己想的,我将他们都用函数式的方式重写了一遍。 这种是在网上抄的,的确非常简洁 function add(a,b) { let res='',c=0; a = a.split(''); b = b.split(''); while (a.le
解决大数相加的方法有很多,网上很容易搜到,下面介绍两种,一种是在网上抄的,一种是自己想的,我将他们都用函数式的方式重写了一遍。 这种是在网上抄的,的确非常简洁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+/,''); } 函数式重写,重点在尾递归,这是在函数式编程中代替 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,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,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,a); 下面这种写法,很不优雅 let addMap = (a,splitAndReverse))(a); 最好compose可以实现组合任意个函数,效果如下 let addMap = (a,b) => compose(R.join(""),myReverse,myReduce(b),splitAndReverse)(a); 实现思路在:https://github.com/zhuanyongx... 我在github https://github.com/zhuanyongx... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |