不幸的是,JavaScript的內置數據類型 - 尤其是Map
- 對完成此任務並不是很有幫助,因爲它們缺少相關方法。
在大多數情況下,大多數條目將落入多個連續的 範圍內,具有相同的值。
但是,我們可以利用這個並在排序數組上使用二分搜索策略,假設轉換表不會經常修改。
通過將每個輸入範圍的最低值存儲在排序數組中,對連續輸入範圍進行編碼,從而導致相同的狀態。保持狀態在一個單獨的數組對應的指標:
let inputs = [0, 5, 10]; // Input ranges [0,4], [5,9], [10,∞)
let states = [0, 1, 0 ]; // Inputs [0,4] lead to state 0, [5,9] to 1, [10,∞) to 0
現在,給定一個輸入,則需要進行輸入陣列類似的二進制搜索到Java's floorEntry(k):
// Returns the index of the greatest element less than or equal to
// the given element, or undefined if there is no such element:
function floorIndex(sorted, element) {
let low = 0;
let high = sorted.length - 1;
while (low <= high) {
let mid = low + high >> 1;
if (sorted[mid] > element) {
high = mid - 1;
} else if (sorted[mid] < element) {
low = mid + 1;
} else {
return mid
}
}
return low - 1;
}
// Example: Transition to 1 for emoticons in range 1F600 - 1F64F:
let transitions = {
inputs: [0x00000, 0x1F600, 0x1F650],
states: [0, 1, 0 ]
};
let input = 0x1F60B; //
let next = transitions.states[floorIndex(transitions.inputs, input)];
console.log(`transition to ${next}`);
此搜索在O(log n)步驟中完成,其中n是連續輸入範圍的數目。單個狀態的轉換表則具有O(n)的空間要求。只要我們的初始假設 - 導致相同狀態的連續輸入範圍的數量很小,這種方法對於稀疏和密集轉換表格同樣適用。
由於(現代)的JavaScript數組本身_sparse_,應該不是內存問題http://stackoverflow.com/questions/4524067/if-i-set-only-a-high-index-in-an-陣列 - 做它浪費內存;許多數組元素也可以引用相同的對象,這會在遇到範圍時爲您節省大量空間。 –
@StephenP雖然問題是關於映射到整數。你必須包裝整數才能引用它們(因爲它們是原始類型),所以引用實際上會更慢。 –
拍完@Aurel –