JavaScript实现从数组中选出和等于固定值的n个数
现实生活中的问题,可能会抽象为这样一种数据模型:
从一个数组中挑选出几个数,让这几个数相加的和为指定的值。
大多数读者应该有过网购的经历,网购一般会有个凑单功能,假如读者买了70元的商品,但是必须满100元才能包邮,这时系统会自动推荐一些商品,加起来差不多就100块钱了。
系统如何确定推荐哪些商品呢?这其实就是刚刚提到的模型,我们可以把热销商品的价格放到一个数组中,然后利用算法,找出数组中哪些价格的和为30元。
废话少说,小菜给大家分享一个JavaScript版本的算法实现。
算法代码:
functiongetCombBySum(array,sum,tolerance,targetCount){ varutil={ /* getcombinationfromarray arr:targetarray num:combinationitemlength return:onearraythatcontaincombinationarrays */ getCombination:function(arr,num){ varr=[]; (functionf(t,a,n) { if(n==0) { returnr.push(t); } for(vari=0,l=a.length;i<=l-n;i++) { f(t.concat(a[i]),a.slice(i+1),n-1); } })([],arr,num); returnr; }, //takearrayindextoaarray getArrayIndex:function(array){ vari=0, r=[]; for(i=0;i<array.length;i++){ r.push(i); } returnr; } },logic={ //sortthearray,thengetwhat'sweneed init:function(array,sum){ //clonearray var_array=array.concat(), r=[], i=0; //sortbyasc _array.sort(function(a,b){ returna-b; }); //getallnumberwhenit'slessthanorequalsum for(i=0;i<_array.length;i++){ if(_array[i]<=sum){ r.push(_array[i]); }else{ break; } } returnr; }, //importantfunction core:function(array,sum,arrayIndex,count,r){ vari=0, k=0, combArray=[], _sum=0, _cca=[], _cache=[]; if(count==_returnMark){ return; } //getcurrentcountcombination combArray=util.getCombination(arrayIndex,count); for(i=0;i<combArray.length;i++){ _cca=combArray[i]; _sum=0; _cache=[]; //calculatethesumfromcombination 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; //checkdata _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); returnr; }
调用说明:
array:数据源数组。必选。
sum:相加的和。必选。
tolerance:容差。如果不指定此参数,则相加的和必须等于sum参数,指定此参数可以使结果在容差范围内浮动。可选。
targetCount:操作数数量。如果不指定此参数,则结果包含所有可能的情况,指定此参数可以筛选出固定数量的数相加,假如指定为3,那么结果只包含三个数相加的情况。可选。
返回值:返回的是数组套数组结构,内层数组中的元素是操作数,外层数组中的元素是所有可能的结果。