javascript 數(shù)組的正態(tài)分布排序的問題
最近幾天頂著上海40°的涼爽天氣找工作,心里是開心的不要不要的,每次面試都是要坐那里出半天汗才能回過神來,感覺到了這個(gè)世界對我深深的愛意,言歸正傳,面試過程中碰到了幾次筆試,其中有這么一道題,由于實(shí)際工作中沒遇到過,所以留意下來,題目是這樣:
有一個(gè)數(shù)組為:var arr = [1,2,1,3,3,2,4,6,3],通過處理將其變?yōu)檎龖B(tài)分布的形式: [1,2,3,3,6,4,3,2,1]。
關(guān)于正態(tài)分布我就簡單解釋一下吧,其實(shí)看到處理后的數(shù)組大致也能明白,就是兩頭小,中間大,體現(xiàn)到坐標(biāo)軸里的正態(tài)曲線呈鐘型,兩頭低,中間高,左右對稱因其曲線呈鐘形,因此人們又經(jīng)常稱之為鐘型曲線。
這道是面試的最后一題,做到這里的時(shí)候時(shí)間比較緊張了加上天氣炎熱口渴饑餓前臺妹子太好看(別廢話了就是因?yàn)樗惴ㄈ酢?。。),稍作思考寫了如下代碼:
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}) //先將數(shù)組從小到大排列得到 [1, 1, 2, 2, 3, 3, 3, 4, 6]
for (;i<l;i++){
if(i%2==0){
temp[i/2] = sortArr[i] // 下標(biāo)為偶數(shù)的順序放到前邊
} else {
temp[l-(i+1)/2] = sortArr[i] // 下標(biāo)為奇數(shù)的從后往前放
}
}
console.log(temp) // [1, 2, 3, 3, 6, 4, 3, 2, 1] 看起來挺完美哈
})(arr)
由于是筆試,自己在腦海里邊yy了一會程序后,覺得沒啥大問題就交卷了,后來的面試官看了試卷,在面試過程中并沒有提到這道題,所以覺得這種方法沒什么問題了就沒在面試過程中再問,不過來回來的路上,我突然想到了一個(gè)這樣的情況:
var arr = [1,2,3,4,5,6,7,8,9] // 一個(gè)規(guī)則遞增的數(shù)組
~(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] 問題出現(xiàn)了。。
})(arr)
是的,這樣一來這個(gè)數(shù)組的左右部分并不是對稱的,以9為中心,左側(cè)為1+3+5+7=16,右側(cè)為2+4+6+8=20,明顯的是左輕右重,不是一個(gè)均勻的正態(tài)分布了,隨著數(shù)組的增大,帶來的問題會越來越嚴(yán)重。
亞麻帶。。。。我是一朵含苞欲放的花骨朵不要這樣對我。。。
看來前邊的代碼是不能用的,只能重新思考解決方法,其實(shí)問題的核心在于保證數(shù)組的左右兩側(cè)是相等或者大致相等的,不管是奇數(shù)個(gè)數(shù)的數(shù)組還是偶數(shù)個(gè)數(shù)的,數(shù)組可以分為兩部分(奇數(shù)個(gè)數(shù)的拋去最大值后也可以看做是一個(gè)偶數(shù)數(shù)組,即便有多個(gè)相同最大值也無所謂,從小到大排序后去除最后一個(gè)即可),還是按照上邊的方法,下標(biāo)為偶數(shù)的時(shí)候放到左側(cè),為奇數(shù)的時(shí)候放到右側(cè),在左右兩邊的數(shù)組增長過程中,當(dāng)數(shù)組長度相等的時(shí)候,對左右兩側(cè)數(shù)組之和進(jìn)行比較,因?yàn)槭前凑諒男〉酱笈帕械?,所以正常情況下,右側(cè)會大于左側(cè),然后將右側(cè)第一個(gè)跟左側(cè)最后一個(gè)互換一下即可達(dá)到平衡的目的,代碼如下:
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) //數(shù)組相等并且右側(cè)和大于左側(cè)的時(shí)候進(jìn)行交換
}
}
}
return temp_left.concat(temp_right)
}
// 數(shù)組求和
function sum(arr) {
return eval(arr.join("+"));
}
// 數(shù)組比較大小
function compare(arr1,arr2) {
return sum(arr1) >= sum(arr2)
}
// 左邊最后一個(gè)跟右邊第一個(gè)交換
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]
這樣一來整個(gè)正態(tài)分布就均勻多了,多做幾組測試看看效果:
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]
看起來還不錯(cuò),小站里還有篇文章 點(diǎn)擊查看,用c++完成的,不過看到文章最后的結(jié)果,并不是一個(gè)均勻的正態(tài)分布,倒是跟我第一個(gè)程序差不多,
本人不怎么會c++,也沒運(yùn)行多組結(jié)果看看,有興趣的同學(xué)可以嘗試下作為對比。
本文所有的程序我僅在chrome做過測試,如果其他瀏覽器有問題的話,希望留言告知,其實(shí)這東西也沒什么難度,權(quán)當(dāng)一個(gè)記錄吧,有需要的時(shí)候可以用用。
相關(guān)文章
5個(gè)最頂級jQuery圖表類庫插件【jquery插件庫】
這篇文章主要介紹了5個(gè)最頂級jQuery圖表類庫插件【jquery插件庫】,需要的朋友可以參考下2016-05-05
javascript數(shù)據(jù)代理與事件詳解分析
所謂數(shù)據(jù)代理(也叫數(shù)據(jù)劫持),指的是在訪問或者修改對象的某個(gè)屬性時(shí),通過一段代碼攔截這個(gè)行為,進(jìn)行額外的操作或者修改返回結(jié)果。比較典型的是 Object.defineProperty() 和 ES2015 中新增的 Proxy 對象2021-11-11
Javascript中eval函數(shù)的使用方法與示例
JavaScript有許多小竅門來使編程更加容易。其中之一就是eval()函數(shù),這個(gè)函數(shù)可以把一個(gè)字符串當(dāng)作一個(gè)JavaScript表達(dá)式一樣去執(zhí)行它。以下是它的說明2007-04-04
js裝飾設(shè)計(jì)模式學(xué)習(xí)心得
本片文章給大家分享一下作者學(xué)習(xí)Javascript裝飾設(shè)計(jì)模式后的心得以及要點(diǎn)分享,有興趣的朋友參考下。2018-02-02
用JavaScript實(shí)現(xiàn)對話框的教程
這篇文章主要介紹了用JavaScript實(shí)現(xiàn)對話框的教程,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-06-06

