演算法練習06 版本號排序
阿新 • • 發佈:2018-12-03
題目(2018-11-21)
有一個專案,由於多人維護,導致版本號規則,例如:
const version = ['1.45.0', '1.5', '6', '3.3.3.3.3']
現在需要對版本號進行從小到大排序,注意: 1.45.0
是大於1.5
的
實現
直接用sort
函式比較是不行的,sort
函式在比較字串的時候,是比較字串的Unicode進行排序的:
'1' < '2'; // true
'1' < '10'; // false
顯然是行不通的
我的思路是,先將version
陣列成員通過split('.')
拆分成一個個陣列
const version = ['1.45.0', '1.5', '6', '3.3.3.3.3']; const temp = [[1, 45, 0], [1, 5], [6], [3, 3, 3]]
在排序的過程中,分為兩層,外層的核心是利用選擇排序,選擇排序過程中進行數值比較時,比較的成員仍然是兩個陣列:
const a = [1, 45, 0],
b = [1, 5];
這時候再加一層迴圈,用a[k]
去比較b[k]
,比較只要能比較出大小(不等)就結束這一層迴圈,如果相等就繼續
一開始結果總不對,結果發現是忘了處理一種情況,比如:
a[k] > b[k]
是我們要交換位置的條件,這時候要結束內層迴圈,但是a[k] < b[k]
同樣要結束迴圈,只不過不交換位置,否則迴圈繼續就違背了版本號比較的初衷了
程式碼上,首先來複習一下選擇排序
const chooseSort = arr = > { for (let i = 0; i < arr.length; i++) { // 選定首位為最小值 let minIndex = i; for (let j = i; j < arr.length; j++) { // 比較時如果當前項更小,增更新最小值序號 if (arr[j] < arr[minIndex]) { minIndex = j } } // 將最小值排到這一輪迴圈的首位 [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]] } return arr; };
經過上面的解釋,我們現在的關鍵就是將:
if (arr[j] < arr[minIndex]) {
minIndex = j
}
由直接比較替換為:
for (let k = 0; k < temp[j].length; k++) {
if (arr[j][k] < arr[minIndex][k]) {
minIndex = j
}
// 只要不等,就立刻結束最內層遍歷
if (arr[j][k] !== arr[minIndex][k]) {
break!
}
}
最終的程式碼:
// 使用的是選擇排序 const versionSort = version => { const temp = version.map(v => v.split('.')); for (let i = 0; i < temp.length; i++) { let minIndex = i; for (let j = i; j < temp.length; j++) { for (let k = 0; k < temp[j].length; k++) { const current = +temp[j][k], min = +temp[minIndex][k]; if (current < min) { minIndex = j; } // 只要不等,就立刻結束最內層遍歷! if (current !== min) { break } } } [temp[i], temp[minIndex]] = [temp[minIndex], temp[i]]; } return temp.map(v = > v.join('.')) }; const version1 = ['1.45.0', '1.5', '6', '3.3.3.3.3']; console.log(versionSort(version1)); // ["1.5", "1.45.0", "3.3.3.3.3", "6"] const version2 = ['0.1.1', '2.3.3', '0.3002.1', '4.2', '4.3.5', '4.3.4.5']; console.log(versionSort(version2)); // ["0.1.1", "0.3002.1", "2.3.3", "4.2", "4.3.4.5", "4.3.5"]
本人水平有限,如果程式碼有誤或者更好的思路,希望賜教。