多个数组的排列组合

共 2942字,需浏览 6分钟

 ·

2022-01-07 21:41


现在有一批手机,其中颜色有['白色','黑色','金色'];内存大小有['16G','32G','64G'],版本有['移动','联通','电信'],要求写一个算法,实现[['白色','16G','移动'], ['白色','16G','联通'] ...]这样的组合,扩张,如果后面还有参数,比如再加一个['国行','港版'],不改程序一样可以执行!


不知道要实现的需求大家听懂了没有,下面我会一步步实现,教大家怎么写:


最后得到的结果是一个数组里面包含若干个数组,看着挺复杂的,我们先实现一个简化版的,数组里面不是数组,而是字符串连接的结果,嗯,先一步步来吧:


第一步,想想通过什么技术来实现,你看这数组之间不断的重组,很容易想到用回调函数,一遍一遍的执行,大致知道用什么技术,接下来就是写思路了,看看下面:


// 执行组合排列的函数function doExchange(arr){
}
//执行var arr = [['a', 'b', 'c'], [1, 2, 3], ['x', 'y', 'z']];var arr1 = [['a','b','c']];//doExchange(arr);console.log(doExchange(arr));


呐,我们建一个函数 doExchange(),表示我们执行排序的主函数,然后当执行 arr 的时候,输出['a1x','a1y' ...]这样的结果,如果是 arr1 呢?我们需要输出['a','b','c'],这好理解哈,现在的重点就是这个主函数了,下面主要讲主函数的实现过程。


// 执行组合排列的函数function doExchange(arr){  var len = arr.length;  // 当数组大于等于2个的时候  if(len >= 2){
}else{ return arr[0]; }}


我们的思路是,当参数里面的数组长度大于2个,比如2个,3个或更多,就执行我们的组合代码,否则只有一个,就直接输出来呗。


如果是大于2个呢?我们的思路是先进行第一个和第二个的合并,2个数组合并成一个数组,然后这个数组再放到参数数组中第一个位置,把原来前两个去掉,相当于是用这个数组替换前两个,没听懂哈,没关系,我们直接看代码:


if (len >= 2) {  // 第一个数组的长度  var len1 = arr[0].length;  // 第二个数组的长度  var len2 = arr[1].length;  // 2个数组产生的组合数  var lenBoth = len1 * len2;  //  申明一个新数组,做数据暂存  var items = new Array(lenBoth);  // 申明新数组的索引  var index = 0;  // 2层嵌套循环,将组合放到新数组中  for (var i = 0; i < len1; i++) {    for (var j = 0; j < len2; j++) {      items[index] = arr[0][i] + arr[1][j];      index++;    }  }}


呐,这里我们先获取第一个和第二个数组的长度,然后计算出它们有多少种组合方式,然后新建一个暂存的数组,用来存我们组合得到的结果,后面就是用双层循环,做字符串连接,放到暂存数组中,没什么好说的。


我们得到了前两个的组合结果,依据我们的思路,是要把它和原来数组合并成一个新数组。


// 第一个数组的长度var len1 = arr[0].length;// 第二个数组的长度var len2 = arr[1].length;// 2个数组产生的组合数var lenBoth = len1 * len2;//  申明一个新数组,做数据暂存var items = new Array(lenBoth);// 申明新数组的索引var index = 0;// 2层嵌套循环,将组合放到新数组中for (var i = 0; i < len1; i++) {  for (var j = 0; j < len2; j++) {    items[index] = arr[0][i] + arr[1][j];    index++;  }}// 将新组合的数组并到原数组中var newArr = arr.slice(2)newArr.unshift(items)


整体的思路就是这样,得到的新数组就是剩下的未组合的数组了,到这里大家应该就豁然开朗了,然后使用递归再次调用这个过程,这样不断组合成新数组,那这个新数组当参数时,如果数组的长度等于1了,就说明组合完了,就会执行后面的 else 语句,输出出来。


整体代码贴出来感受一下:

function doExchange(arr) {  var len = arr.length;  // 当数组大于等于2个的时候  if (len >= 2) {    // 第一个数组的长度    var len1 = arr[0].length;    // 第二个数组的长度    var len2 = arr[1].length;    // 2个数组产生的组合数    var lenBoth = len1 * len2;    //  申明一个新数组,做数据暂存    var items = new Array(lenBoth);    // 申明新数组的索引    var index = 0;    // 2层嵌套循环,将组合放到新数组中    for (var i = 0; i < len1; i++) {      for (var j = 0; j < len2; j++) {        items[index] = arr[0][i] + arr[1][j];        index++;      }    }    // 把已经合并过的数组删除掉,将新组合的数组并到原数组中    var newArr = arr.slice(2)    newArr.unshift(items)    // 执行回调    return doExchange(newArr);  } else {    return arr[0];  }}


输出结果:

[  'a1x', 'a1y', 'a1z', 'a2x',  'a2y', 'a2z', 'a3x', 'a3y',  'a3z', 'b1x', 'b1y', 'b1z',  'b2x', 'b2y', 'b2z', 'b3x',  'b3y', 'b3z', 'c1x', 'c1y',  'c1z', 'c2x', 'c2y', 'c2z',  'c3x', 'c3y', 'c3z']


浏览 41
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报