javascript 数组的正态分布排序的问题


Posted in Javascript onJuly 31, 2016

最近几天顶着上海40°的凉爽天气找工作,心里是开心的不要不要的,每次面试都是要坐那里出半天汗才能回过神来,感觉到了这个世界对我深深的爱意,言归正传,面试过程中碰到了几次笔试,其中有这么一道题,由于实际工作中没遇到过,所以留意下来,题目是这样:

有一个数组为:var arr = [1,2,1,3,3,2,4,6,3],通过处理将其变为正态分布的形式: [1,2,3,3,6,4,3,2,1]。

关于正态分布我就简单解释一下吧,其实看到处理后的数组大致也能明白,就是两头小,中间大,体现到坐标轴里的正态曲线呈钟型,两头低,中间高,左右对称因其曲线呈钟形,因此人们又经常称之为钟型曲线。

这道是面试的最后一题,做到这里的时候时间比较紧张了加上天气炎热口渴饥饿前台妹子太好看(别废话了就是因为算法弱。。。),稍作思考写了如下代码:

var arr = [1,2,1,3,3,2,4,6,3]
 ~(function(arr) {
  var temp = [], i = 0, l = arr.length,
   sortArr = arr.sort(function(a,b){return a-b}) //先将数组从小到大排列得到 [1, 1, 2, 2, 3, 3, 3, 4, 6]
for (;i<l;i++){
   if(i%2==0){
    temp[i/2] = sortArr[i] // 下标为偶数的顺序放到前边
   } else {
    temp[l-(i+1)/2] = sortArr[i] // 下标为奇数的从后往前放
   }
  }

  console.log(temp) // [1, 2, 3, 3, 6, 4, 3, 2, 1] 看起来挺完美哈
 })(arr)

由于是笔试,自己在脑海里边yy了一会程序后,觉得没啥大问题就交卷了,后来的面试官看了试卷,在面试过程中并没有提到这道题,所以觉得这种方法没什么问题了就没在面试过程中再问,不过来回来的路上,我突然想到了一个这样的情况:

var arr = [1,2,3,4,5,6,7,8,9] // 一个规则递增的数组
 ~(function(arr) {
  var temp = [], i = 0, l = arr.length,
   sortArr = arr.sort(function(a,b){return a-b})
  
  for (;i<l;i++){
   if(i%2==0){
    temp[i/2] = sortArr[i]
   } else {
    temp[l-(i+1)/2] = sortArr[i]
   }
  }
  
  console.log(temp) //[1, 3, 5, 7, 9, 8, 6, 4, 2] 问题出现了。。
 })(arr)

是的,这样一来这个数组的左右部分并不是对称的,以9为中心,左侧为1+3+5+7=16,右侧为2+4+6+8=20,明显的是左轻右重,不是一个均匀的正态分布了,随着数组的增大,带来的问题会越来越严重。

亚麻带。。。。我是一朵含苞欲放的花骨朵不要这样对我。。。

看来前边的代码是不能用的,只能重新思考解决方法,其实问题的核心在于保证数组的左右两侧是相等或者大致相等的,不管是奇数个数的数组还是偶数个数的,数组可以分为两部分(奇数个数的抛去最大值后也可以看做是一个偶数数组,即便有多个相同最大值也无所谓,从小到大排序后去除最后一个即可),还是按照上边的方法,下标为偶数的时候放到左侧,为奇数的时候放到右侧,在左右两边的数组增长过程中,当数组长度相等的时候,对左右两侧数组之和进行比较,因为是按照从小到大排列的,所以正常情况下,右侧会大于左侧,然后将右侧第一个跟左侧最后一个互换一下即可达到平衡的目的,代码如下:

var arr = [1,2,3,4,5,6,7,8,9],
  sortArr = arr.sort(function(a,b){return a-b}),
  l = arr.length,
  temp_left = [], temp_right = []

 function sort(arr){
  var i = 0
  for(;i<l;i++){
   var eq = sortArr[i]
   i%2 == 0 ? temp_left.push(eq) : temp_right.unshift(eq)
   if(i > 1){
    if( temp_left.length == temp_right.length && !compare(temp_left, temp_right)){
     wrap(temp_left,temp_right) //数组相等并且右侧和大于左侧的时候进行交换
    }
   }
  }
  return temp_left.concat(temp_right)
 }


 // 数组求和
 function sum(arr) {
  return eval(arr.join("+"));
 }

 // 数组比较大小
 function compare(arr1,arr2) {
  return sum(arr1) >= sum(arr2)
 }

 // 左边最后一个跟右边第一个交换

 function wrap(l,r){
  var m = r.shift()
  r.unshift(l.pop())
  l.push(m)
 }

 console.log(sort(arr)) // 得到 [1, 4, 6, 7, 9, 8, 5, 3, 2]

这样一来整个正态分布就均匀多了,多做几组测试看看效果:

arr = [1,333,444,555,66,7788,909]
console.log(sort(arr)) /[1, 444, 909, 7788, 555, 333, 66]


arr = [168.6,177.5,174.2,189.3,167.2,177.6,167.8,175.5]
console.log(sort(arr)) //[167.2, 174.2, 175.5, 189.3, 177.6, 177.5, 168.6, 167.8]

看起来还不错,小站里还有篇文章 点击查看,用c++完成的,不过看到文章最后的结果,并不是一个均匀的正态分布,倒是跟我第一个程序差不多,

本人不怎么会c++,也没运行多组结果看看,有兴趣的同学可以尝试下作为对比。

 

本文所有的程序我仅在chrome做过测试,如果其他浏览器有问题的话,希望留言告知,其实这东西也没什么难度,权当一个记录吧,有需要的时候可以用用。

Javascript 相关文章推荐
JQuery Tips(3) 关于$()包装集内元素的改变
Dec 14 Javascript
jQuery提交多个表单的小例子
Jun 30 Javascript
jquery简单的拖动效果实现原理及示例
Jul 26 Javascript
Javascript玩转继承(二)
May 08 Javascript
轻松学习jQuery插件EasyUI EasyUI表单验证
Dec 01 Javascript
JavaScript+HTML5实现的日期比较功能示例
Jul 12 Javascript
vue2实现可复用的轮播图carousel组件详解
Nov 27 Javascript
详解webpack提取第三方库的正确姿势
Dec 22 Javascript
深入理解 webpack 文件打包机制(小结)
Jan 08 Javascript
postman+json+springmvc测试批量添加实例
Mar 31 Javascript
解决antd 表单设置默认值initialValue后验证失效的问题
Nov 02 Javascript
Node快速切换版本、版本回退(降级)、版本更新(升级)
Jan 07 Javascript
详细谈谈javascript的对象
Jul 31 #Javascript
JS中使用DOM来控制HTML元素
Jul 31 #Javascript
图解prototype、proto和constructor的三角关系
Jul 31 #Javascript
JavaScript数据类型转换的注意事项
Jul 31 #Javascript
关于JavaScript 原型链的一点个人理解
Jul 31 #Javascript
jquery实现界面无刷新加载登陆注册
Jul 30 #Javascript
AngularJS ng-change 指令的详解及简单实例
Jul 30 #Javascript
You might like
ThinkPHP使用smarty模板引擎的方法
2014/07/01 PHP
php实现根据词频生成tag云的方法
2015/04/17 PHP
使用原生javascript创建通用表单验证——更锋利的使用dom对象
2011/09/13 Javascript
关于js中for in的缺陷浅析
2013/12/02 Javascript
js中window.open()的所有参数详细解析
2014/01/09 Javascript
深入学习jQuery Validate表单验证
2016/01/18 Javascript
原生JS获取元素集合的子元素宽度实例
2016/12/14 Javascript
JS日程管理插件FullCalendar简单实例
2017/02/07 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
JS简单生成随机数(随机密码)的方法
2017/05/11 Javascript
JavaScript数据类型和变量_动力节点Java学院整理
2017/06/26 Javascript
老生常谈js数据类型
2017/08/03 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
2019/03/02 NodeJs
JavaScript函数式编程(Functional Programming)组合函数(Composition)用法分析
2019/05/22 Javascript
vue+Element实现搜索关键字高亮功能
2019/05/28 Javascript
mpvue实现微信小程序快递单号查询代码
2020/04/03 Javascript
Vue数组响应式操作及高阶函数使用代码详解
2020/08/01 Javascript
[06:13]DOTA2进化论(修改版)
2013/10/08 DOTA
[05:46]DOTA2英雄梦之声_第18期_陈
2014/06/20 DOTA
shelve  用来持久化任意的Python对象实例代码
2016/10/12 Python
Python编程实现的图片识别功能示例
2017/08/03 Python
Python cookbook(数据结构与算法)将名称映射到序列元素中的方法
2018/03/22 Python
解决DataFrame排序sort的问题
2018/06/07 Python
Python @property使用方法解析
2019/09/17 Python
基于Numba提高python运行效率过程解析
2020/03/02 Python
使用python处理题库表格并转化为word形式的实现
2020/04/14 Python
用CSS3的box-reflect设置文字倒影效果的方法讲解
2016/03/07 HTML / CSS
英国现代家具和装饰网站:PN Home
2018/08/16 全球购物
美国儿童玩具、装扮和玩偶商店:Magic Cabin
2018/09/02 全球购物
学生实习自我鉴定
2013/10/11 职场文书
航空大学应届生求职信
2013/11/10 职场文书
战略合作意向书范本
2014/04/01 职场文书
银行奉献演讲稿
2014/09/16 职场文书
主持人开幕词
2015/01/29 职场文书
SpringBoot整合minio快速入门教程(代码示例)
2022/04/03 Java/Android