博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个关于JS解决数组相乘问题
阅读量:6893 次
发布时间:2019-06-27

本文共 4082 字,大约阅读时间需要 13 分钟。

数组相乘,顾名思义就是将多个数组的每一元素乘(组合)起来。它的结果以几何数级增长,初次遇到此类问题时,常常使人头皮发麻,我们现在以js的角度来解决这个问题。

从实例出发

众所周知,女孩出门前一般需要经过精心打扮,那么假设你有一个女朋友,她有着3顶帽子,5件衣服,5条裤子,3双鞋子,2只口红,4个包包,2副墨镜,且心情可能会影响穿着,她可能因为心情不好而选择不带一些物品,但是她会告诉你她会穿戴什么,要求列举所有方案,看到题目后……

不说了,先将实际问题转化成语言问题吧。
七个数组,分别表示七种穿戴,数组中存值为该穿戴的代号,传值为字符串是她告诉你她需要的穿着,例"clothes trousers",中间以空格隔开

const hat = ['a','b','c'];const clothes = ['0','1','2','3','4'];const trousers = ['q','w','e','r','t'];const shoes = ['A','B','C'];const lipstick = ['$1','$2'];const bag = ['¥1','¥2','¥3','¥4'];const sunglasses = ['^1','^2'];function getComb(str){    return arr;}复制代码

解决思路

秉着不管什么问题,看到数组我就用循环的思路,去解题,难免会遇上很多问题。如果,题目上明确指出女朋友心情必须max每次出门都装备拉满,那ok没问题,7次循环解决。但是女人心海底针呐,你只能通过她告诉的穿着来列举(如果无论什么情况,你都用7次循环,那当我没说)。

随机数法

我们可以让电脑自己随机组合,并判断如果已经添加过这个结果,就不加进数组就ok了。

const arr = str.split(' ')    .map(name => {        switch (name) {            case 'hat': return hat;            case 'clothes': return clothes;            case 'trousers': return trousers;            case 'shoes': return shoes;            case 'lipstick': return lipstick;            case 'bag': return bag;            case 'sunglasses': return sunglasses;        }    })复制代码

先将传入的字符串转化一个与它传值相关的二维数组,例:传入"hat clothes"

arr为[ [ 'a', 'b', 'c' ], [ '0', '1', '2', '3', '4' ] ],这样我们就得知了穿戴的数目,以及该穿戴的种类了。我们不难得出,这种情况下最多能列出15种结果,定义一个total变量并修改一下上面代码。

let total = 1;const arr = str.split(' ')    .map(name => {        switch (name) {            case 'hat': total *= hat.length ; return hat;            case 'clothes': total *= clothes.length ; return clothes;            case 'trousers': total *= trousers.length ; return trousers;            case 'shoes': total *= shoes.length ; return shoes;            case 'lipstick': total *= lipstick.length ; return lipstick;            case 'bag': total *= bag.length ; return bag;            case 'sunglasses': total *= sunglasses.length ; return sunglasses;        }    })复制代码

如果使用随机数我们就能将一个多次循环转化为一个while判断的for循环。我们new一个数组result,由于我们知道一共有几种结果,所以while循环的条件就是:result.length < total.

let result = [], sum = '';    while (result.length < total) {        for (let i = 0; i < arr.length; i++) {            sum += arr[i][parseInt(Math.random() * arr[i].length)];        }        if (result.indexOf(sum) == -1)            result.push(sum);        sum = '';    }    return result;复制代码

注意:Math.random()是产生一个[0,1)的随机浮点数,数组的索引是整数,所以我们需要转换类型;sum是数组的组合,所以我们在添加完后需要了给它还原.

随机数法的缺点:

算法过于暴力,由于Math.random值返回的不确定性,导致很多时间会浪费在生成一个数组已经添加过的值上。

reduce方法

我们也可以使用reduce方法非常简便的完成数组的乘法.很多初学者可能会对reduce比较陌生,因为这是一个不常见的方法,但是使用reduce进行很方便,先简单介绍一下reduce方法。

reduce方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终为一个值

reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。

arr.reduce(callback,[initialValue])callback (执行数组中每个值的函数,包含四个参数)previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))currentValue (数组中当前被处理的元素)index (当前元素在数组中的索引)array (调用 reduce 的数组)initialValue (作为第一次调用 callback 的第一个参数。)复制代码

基础用法

const a = [1,2,3,4,5,6];    const rst = a.reduce((pre,cur)=>{        return pre + cur;    })    console.log(rst); // rst = 1+2+3+4+5+6复制代码

pre为第一个值或上次计算的结果,这里没有传初值,pre初始默认为0,cur为数组的每一个值。这里解析过程:

=> pre = 0 ; cur = a[0];=> pre = 0 + a[0] ; cur = a[1];=> pre = 0 + a[0] + a[1] ; cur = a[2];...rst = 0 + 1 + 2 + 3 + 4 + 5 + 6 // 21复制代码

用reduce解决数组相乘

return arr.reduce((pre,cur)=>{        return [].concat(...pre.map(e=>cur.map(ele=>ele+e)))    }) 复制代码

例:

str = 'clothes hat bag';=> arr :[ [ '0', '1', '2', '3', '4' ],  [ 'a', 'b', 'c' ],  [ '¥1', '¥2', '¥3', '¥4' ] ]复制代码

首先将一个复杂组合问题,转化为叠加组合问题。如果能将arr[0],arr[1]两个组合的结果返回给pre,那么我们就能通过两两组合来完成复杂组合。接下来使用map完成两两组合:

pre : [ '0', '1', '2', '3', '4' ]cur : [ 'a', 'b', 'c' ]pre.map(e => cur.map(ele => e + ele));/*第一次*/e : '0' , ele: 'a' , e + ele ='0a', pre[['0a']]e : '0' , ele: 'b' , e + ele = '0b', pre[['0a','0b']].../*结束*/pre[['0a','0b','0c'],['1a','1b','1c'],['2a','2b','2c'],['3a','3b','3c'],['4a','4b','4c' ]]cur : [ '¥1', '¥2', '¥3', '¥4' ]复制代码

接下来我们只需要将二维数组pre转化为一维数组,然后函数就会随着reduce一步一步将数组相乘起来了

[].concat[...pre.map(e => cur.map(ele => e + ele))]复制代码

扩展运算符( spread )是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,一般在传参时使用。

到这里我们就解决这个女朋友出门的问题了。

转载地址:http://dtebl.baihongyu.com/

你可能感兴趣的文章
‘撤消或允许’重载
查看>>
TensorFlow人工智能引擎入门教程之十 最强网络 RSNN深度残差网络 平均准确率96-99%...
查看>>
关于访问Android项目中assets中的资源
查看>>
大家来解一解小学生题目......
查看>>
CentOS 6.4 & 6.5下DRBD的安装配置
查看>>
wp-setting.php文件详解
查看>>
mysqldb安装
查看>>
DOS 的XCOPY命令的应用之排除某些文件或文件夹(/EXCLUDE选项的应用)
查看>>
如何才能带动团队
查看>>
Spring中IOC和AOP的详细解释
查看>>
电机分类
查看>>
IntelliJ Idea 常用快捷键列表
查看>>
一、数组二三
查看>>
Android_触摸设备
查看>>
mysql读书笔记(三)
查看>>
实例:调用系统字体
查看>>
程序员应该重视版本控制
查看>>
提升Salt Api稳定性
查看>>
sqoop架构原理与操作
查看>>
C Primer Plus 第5章 运算符、表达式和语句 5.6 带有参数的函数
查看>>