前言:
现在大家对“js几率”大体比较关心,大家都想要知道一些“js几率”的相关内容。那么小编同时在网摘上汇集了一些有关“js几率””的相关知识,希望朋友们能喜欢,看官们快快来学习一下吧!前言
最近在自己的群里遇到一道关于使用Javascript解决算法问题的讨论,最终答案的代码很简洁,我自己也进行了整理,这里和大家分享下。
题目
题目的内容是这样的:一个人投篮12次,命中8球,命中编号1,未命中编号0,那么1次投篮的可能性我们可以编码为000011111000,那么这个人连续投中4个球及以上的概率有多大?
这里我选择了其中一种穷举法,因为它实现的方法很巧妙。注意:这种方法不是最优方法。
分析
既然选择穷举法,必定要列举出所有可能的情况,然后判断满足条件的情况。整个分析过程我们分为4步。
第一步-获取数组
一个人投12次篮,投中为1,未投中为0,那么每次投篮都会有2种情况,总的情况就是2*2*2...*2=4096种情况,实际从二进制上看就是000000000000-111111111111中所有二进制值的个数。
这样的话我们可以定义一个数组,里面包含所有可能的情况值。
但是这个数组我们怎么获取呢?这是算法的第一步。
这里有个很巧妙的方法就是利用数组索引,我们定义一个长度为4096的空数组,那么数组的索引就是从0-4095了。
这里我们就可以得到第一步的代码。
其中0xfff表示的是16进制的数fff,表示的是4095,再加上1,就是整个数组的长度4096,然后将其用扩展运算符展开成数组。
map方法就是专门输出索引值,上述代码运行后得到的结果是[0,1,2,3...4095]。
第二步-过滤其中包含8个1的值
第二步就是过滤出投中8次篮的值,即二进制编码中包含8个1的值。
这里我们需要定义一个过滤函数isContainEightOne,判断其中是否包含8个1。
判断的方法也很简单,首先将十进制值转化为二进制,再将二进制数的每一位进行相加,如果等于8则代表符合条件,不等于8则代表不符合。
因此可以得到以下方法。
因为Javascript中数组的语法是支持链式调用的,我们可以继续在第一步的后面补充如下filter方法。
第三步-过滤连续4个1及以上
过滤出连续投中4次及以上的值,即包含连续4个1或者更多的值。
首先将索引数字转化为二进制数,然后通过正则表达式去匹配'1111',只要匹配到了就表示符合条件,这里也包括连续5个1,连续6个1等的情况。
我们可以得出下列代码。
第四步-计算概率
第二个filter方法后得到的就是满足条件的值,获取到其长度后,就是所有可能的情况,然后除以总数即可。
最终代码
将上述代码进行整合,得到最终完整形态的代码。
结束语
今天这道Javascript实现的关于概率方面的算法题,虽然在效率上并不是最优的,但是其短巧精妙的代码却很吸引我,这也是我专门写这篇文章的原因。
后续如果看到了类似的巧妙代码解决的问题,我还会将它整理出来。
标签: #js几率