UNPKG

w-component-vue

Version:
92 lines (82 loc) 2.45 kB
import size from 'lodash-es/size.js' import filter from 'lodash-es/filter.js' import maxBy from 'lodash-es/maxBy.js' /** * 二元搜索法(Binary Search),通過fGetValue(index)取值,求最靠近0但小於0的值,並回傳值與所在的index與所查得的數據items[index] * * @param {Array} items 輸入欲搜尋陣列 * @param {Function} fGetValue 輸入取值函數,傳入index * @returns {Object} 回傳物件index,最靠近0但小於0的值、所在的index與所查得的數據items[index] */ function binarySearch(items, fGetValue) { let n = size(items) let iStart = 0 let vStart = fGetValue(iStart) let iEnd = n - 1 let vEnd = fGetValue(iEnd) let run = true let index = null while (run) { let iMiddle = Math.floor((iEnd + iStart) / 2) let vMiddle = fGetValue(iMiddle) //console.log(`iStart=${iStart}, vStart=${vStart}, iMiddle=${iMiddle}, vMiddle=${vMiddle}, iEnd=${iEnd}, vEnd=${vEnd}`) //check if (vStart < 0 && vMiddle < 0 && vEnd < 0) { index = null run = false break } else if (vStart > 0 && vMiddle > 0 && vEnd > 0) { index = null run = false break } else if (vStart === 0) { index = iStart run = false break } else if (vMiddle === 0) { index = iMiddle run = false break } else if (vEnd === 0) { index = iEnd run = false break } else if (iMiddle === iStart || iMiddle === iEnd) { let rs = [{ i: iStart, v: vStart, }, { i: iMiddle, v: vMiddle, }, { i: iEnd, v: vEnd, }] rs = filter(rs, (v) => { return v.v <= 0 }) let r = maxBy(rs, 'v') index = r.i run = false break } //update if (vStart * vMiddle > 0) { iStart = iMiddle vStart = vMiddle } else { iEnd = iMiddle vEnd = vMiddle } } return index } export default binarySearch