LINE BOT 開發紀錄 - 薪資級距確認篇(Binary Search)
本篇使用 JavaScript 來說明。
前言
最近在開發的 line bot 是讓使用者提供自己的薪資(target),然後在我幫他確認完薪資級距後,提供該級距的相關資訊。「確認薪資級距」這個動作簡單來說,就是在一個「有序」數字陣列(numArray)中,找到使用者提供的薪資屬於這個陣列中的哪個區間?
在開始前有考慮過兩種搜尋法: Linear Search(線性搜尋)、Binary Search(二分搜尋)。考慮到基本工資以上的所有級距約有 50 個,Binary Search 會是個比較有效率的做法。之前在 CS50x 課程的 week0 有介紹二分搜尋法的概念,這次剛好可以來做個實踐。
Binary Search 實作
使用 Binary Search 要記得,它是針對「有序陣列」進行搜尋,所以開始之前要先幫陣列進行排序。
在陣列中尋找特定元素
Binary Search 是直接在陣列中搜尋特定元素。
因為是把陣列不斷切半再切半的尋找,而整個過程都是不斷重複的,所以這邊使用遞回函式(recusion)來完成。
1 |
|
LINE BOT 實作調整
針對薪資級距查詢有兩個需要調整的地方:
- 薪資級距的套用有一個特性: 除了超過最高級距的狀況,套用的級距必須高於給定的薪資。
- 給定的 target 即使不在 numArray 裡,最後也會回傳一個符合條件的數字。
首先,在切分 numArray
時,由於級距必須要比薪資高,所以 array.slice()
的起始點和結束點都需要調整,要從 middleIndex
再向後一位切起。
1 |
|
接下來,因為切分位置的改變,middleIndex
也需要調整。避免 numArray.length === 2
時,因為 numArray.slice(0, middleIndex + 1)
,造成陣列無法切小。
1 |
|
最後,設置遞迴的結束點: 當陣列不斷被切小後,只會剩下一個最終結果,只要把這個結果 return 就好。
1 |
|
到目前為止其實已經確認可以得出正確級距,但是還有再優化的空間: 例如 target === numArray[middleIndex]
,依照目前邏輯還是必須切到剩最後一個才會 return ,會多出一些不必要的步驟。所以可以把這個狀況也加進遞迴停止條件中。最後的程式碼會是這個樣子:
1 |
|
參考資料
pjchender - [演算法] Binary Search:在陣列中尋找特定元素
文章內容如有錯誤,歡迎留言討論!
本 Blog 上的所有文章除特别聲明外,均採用 CC BY-SA 4.0 協議 ,轉載請註明出處!