JavaScript实现从数组中选出和等于固定值的n个数


Posted in Javascript onSeptember 03, 2014

现实生活中的问题,可能会抽象为这样一种数据模型:

从一个数组中挑选出几个数,让这几个数相加的和为指定的值。

大多数读者应该有过网购的经历,网购一般会有个凑单功能,假如读者买了70元的商品,但是必须满100元才能包邮,这时系统会自动推荐一些商品,加起来差不多就100块钱了。

系统如何确定推荐哪些商品呢?这其实就是刚刚提到的模型,我们可以把热销商品的价格放到一个数组中,然后利用算法,找出数组中哪些价格的和为30元。

废话少说,小菜给大家分享一个JavaScript版本的算法实现。

算法代码:

function getCombBySum(array,sum,tolerance,targetCount){
var util = {
/*
get combination from array
arr: target array
num: combination item length
return: one array that contain combination arrays
*/
getCombination: function(arr, num) {
var r=[];
(function f(t,a,n)
{
if (n==0)
{
return r.push(t);
}
for (var i=0,l=a.length; i<=l-n; i++)
{
f(t.concat(a[i]), a.slice(i+1), n-1);
}
})([],arr,num);
return r;
},
//take array index to a array
getArrayIndex: function(array) {
var i = 0,
r = [];
for(i = 0;i<array.length;i++){
r.push(i);
}

return r;
}
},logic = {
//sort the array,then get what's we need
init: function(array,sum) {
//clone array
var _array = array.concat(),
r = [],
i = 0;
//sort by asc
_array.sort(function(a,b){
return a - b;
});
//get all number when it's less than or equal sum
for(i = 0;i<_array.length;i++){
if(_array[i]<=sum){
r.push(_array[i]);
}else{
break;
}
}

return r;
},
//important function
core: function(array,sum,arrayIndex,count,r){
var i = 0,
k = 0,
combArray = [],
_sum = 0,
_cca = [],
_cache = [];

if(count == _returnMark){
return;
}
//get current count combination
combArray = util.getCombination(arrayIndex,count);
for(i = 0;i<combArray.length;i++){
_cca = combArray[i];
_sum = 0;
_cache = [];
//calculate the sum from combination
for(k = 0;k<_cca.length;k++){
_sum += array[_cca[k]];
_cache.push(array[_cca[k]]);
}
if(Math.abs(_sum-sum) <= _tolerance){
r.push(_cache);
} 
}

logic.core(array,sum,arrayIndex,count-1,r);
}

},
r = [],
_array = [],
_targetCount = 0,
_tolerance = 0,
_returnMark = 0;

//check data
_targetCount = targetCount || _targetCount;
_tolerance = tolerance || _tolerance;

_array = logic.init(array,sum);
if(_targetCount){
_returnMark = _targetCount-1;
}

logic.core(_array,sum,util.getArrayIndex(_array),(_targetCount || _array.length),r);

return r;
}

调用说明:

array: 数据源数组。必选。

sum: 相加的和。必选。

tolerance: 容差。如果不指定此参数,则相加的和必须等于sum参数,指定此参数可以使结果在容差范围内浮动。可选。

targetCount: 操作数数量。如果不指定此参数,则结果包含所有可能的情况,指定此参数可以筛选出固定数量的数相加,假如指定为3,那么结果只包含三个数相加的情况。可选。

返回值:返回的是数组套数组结构,内层数组中的元素是操作数,外层数组中的元素是所有可能的结果。

Javascript 相关文章推荐
用jquery方法操作radio使其默认选项是否
Sep 10 Javascript
JavaScript获取网页中第一个链接ID的方法
Apr 03 Javascript
浅谈Javascript中substr和substring的区别
Sep 30 Javascript
搞定immutable.js详细说明
May 02 Javascript
Javascript动画效果(3)
Oct 11 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
Apr 14 Javascript
webpack组织模块打包Library的原理及实现
Mar 10 Javascript
基于Vue实现拖拽效果
Apr 27 Javascript
基于Vue中使用节流Lodash throttle详解
Oct 30 Javascript
js实现圆形显示鼠标单击位置
Feb 11 Javascript
Chrome插件开发系列一:弹窗终结者开发实战
Oct 02 Javascript
Vue实现tab导航栏并支持左右滑动功能
Jun 28 Vue.js
JavaScript实现找出数组中最长的连续数字序列
Sep 03 #Javascript
js实现的类似于asp数据字典的数据类型代码实例
Sep 03 #Javascript
jQuery表格列宽可拖拽改变且兼容firfox
Sep 03 #Javascript
Egret引擎开发指南之视觉编程
Sep 03 #Javascript
Egret引擎开发指南之发布项目
Sep 03 #Javascript
Egret引擎开发指南之运行项目
Sep 03 #Javascript
JavaScript实现找出字符串中第一个不重复的字符
Sep 03 #Javascript
You might like
zend framework配置操作数据库实例分析
2012/12/06 PHP
Laravel 5.3 学习笔记之 安装
2016/08/28 PHP
yii2 数据库读写分离配置示例
2017/02/10 PHP
分享精心挑选的12款优秀jQuery Ajax分页插件和教程
2012/08/09 Javascript
caller和callee的区别介绍及演示结果
2013/03/10 Javascript
JQuery插件开发示例代码
2013/11/06 Javascript
js单词形式的运算符
2014/05/06 Javascript
ECMAScript6函数默认参数
2015/06/12 Javascript
javascript实现显示和隐藏div方法汇总
2015/08/14 Javascript
Angular.js与Bootstrap相结合实现表格分页代码
2016/04/12 Javascript
AngularJS的ng-repeat指令与scope继承关系实例详解
2017/01/21 Javascript
JavaScript实现公历转农历功能示例
2017/02/13 Javascript
vue-dialog的弹出层组件
2020/05/25 Javascript
微信小程序自定义模态对话框实例详解
2017/08/16 Javascript
Vue 实现树形视图数据功能
2018/05/07 Javascript
详解使用React制作一个模态框
2019/03/14 Javascript
解决vue v-for src 图片路径问题 404
2019/11/12 Javascript
使用原生JS实现滚轮翻页效果的示例代码
2020/05/31 Javascript
vue的$http的get请求要加上params操作
2020/11/12 Javascript
[19:14]DOTA2 HEROS教学视频教你分分钟做大人-维萨吉
2014/06/24 DOTA
[02:37]2015国际邀请赛选手档案—LGD.Xiao8
2015/07/28 DOTA
[30:55]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第二场 11.18
2020/11/18 DOTA
Python正则表达式匹配数字和小数的方法
2019/07/03 Python
python十进制转二进制的详解
2020/02/07 Python
解决jupyter notebook打不开无反应 浏览器未启动的问题
2020/04/10 Python
python 实现PIL模块在图片画线写字
2020/05/16 Python
python中np是做什么的
2020/07/21 Python
Python中Yield的基本用法
2020/10/18 Python
在使用非全零作为空指针内部表达的机器上, NULL是如何定义
2014/11/09 面试题
几个SQL的面试题
2014/03/08 面试题
在网络中有两台主机A和B,并通过路由器和其他交换设备连接起来,已经确认物理连接正确无误,怎么来测试这两台机器是否连通?如果不通,怎么来判断故障点?怎么排
2014/01/13 面试题
六查六看自查材料
2014/02/17 职场文书
质量承诺书范文
2014/03/27 职场文书
爱耳日活动总结
2014/04/30 职场文书
法制宣传教育方案
2014/05/09 职场文书
烟台的海导游词
2015/02/02 职场文书