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 相关文章推荐
使用js获取地址栏中传递的值
Jul 02 Javascript
js特殊字符过滤的示例代码
Mar 05 Javascript
JQuery 在线引用及测试引用是否成功
Jun 24 Javascript
jQuery简单实现图片预加载
Apr 20 Javascript
JavaScript 封装一个tab效果源码分享
Sep 15 Javascript
使用jQuery制作浮动工具栏的实例分享
May 13 Javascript
jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页)
May 19 jQuery
深入理解React高阶组件
Sep 28 Javascript
JavaScript数据结构之双向链表定义与使用方法示例
Oct 27 Javascript
微信小程序入口场景的问题集合与相关解决方法
Jun 26 Javascript
layui时间控件选择时间范围的实现方法
Sep 28 Javascript
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
详细谈谈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
与空气斗智斗勇的经典《Overlord》,传说中的“无稽之谈”
2020/04/09 日漫
使用TinyButStrong模板引擎来做WEB开发
2007/03/16 PHP
PHP中的错误处理、异常处理机制分析
2012/05/07 PHP
基于PHP CURL获取邮箱地址的详解
2013/06/03 PHP
destoon调用企业会员公司形象图片的实现方法
2014/08/21 PHP
PHP按符号截取字符串的指定部分的实现方法
2018/09/10 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
2020/02/27 PHP
来自国外的页面JavaScript文件优化
2010/12/08 Javascript
通过js动态操作table(新增,删除相关列信息)
2012/05/23 Javascript
禁用页面部分JavaScript方法的具体实现
2013/07/31 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
2016/02/02 Javascript
Javascript中的Prototype到底是什么
2016/02/16 Javascript
Node.js下自定义错误类型详解
2016/10/17 Javascript
js数组操作方法总结(必看篇)
2016/11/22 Javascript
jquery 给动态生成的标签绑定事件的几种方法总结
2018/02/24 jQuery
关于vue中的ajax请求和axios包问题
2018/04/19 Javascript
vue如何将v-for中的表格导出来
2018/05/07 Javascript
jQuery创建及操作xml格式数据示例
2018/05/26 jQuery
[18:32]DOTA2 HEROS教学视频教你分分钟做大人-谜团
2014/06/12 DOTA
[02:59]2014DOTA2西雅图国际邀请赛 圆满落幕中国夺冠
2014/07/23 DOTA
[35:39]完美世界DOTA2联赛PWL S2 FTD.C vs Rebirth 第二场 11.22
2020/11/24 DOTA
对pandas replace函数的使用方法小结
2018/05/18 Python
Python把csv数据写入list和字典类型的变量脚本方法
2018/06/15 Python
Python设计模式之原型模式实例详解
2019/01/18 Python
Python 实现一个手机号码获取妹子名字的功能
2019/09/25 Python
html5 浏览器支持 如何让所有的浏览器都支持HTML5标签样式
2012/12/07 HTML / CSS
HTML5 CSS3实现一个精美VCD包装盒个性幻灯片案例
2014/06/16 HTML / CSS
HTML5实现音频和视频嵌入的方法
2018/08/22 HTML / CSS
new修饰符是起什么作用
2015/06/28 面试题
竞选大队长演讲稿
2014/04/29 职场文书
开展党的群众路线教育实践活动情况汇报
2014/11/05 职场文书
文化大革命观后感
2015/06/17 职场文书
工作简报格式范文
2015/07/21 职场文书
详解NodeJS模块化
2021/06/15 NodeJs
使用Spring处理x-www-form-urlencoded方式
2021/11/02 Java/Android
Python实现制作销售数据可视化看板详解
2021/11/27 Python