簡體   English   中英

如何在數組中存儲哪些索引范圍是空閑的?

[英]How to store which index ranges are free in an array?

假設您有一個存儲任意對象的大型數組。 object 時不時地從這里刪除並在那里刪除。 現在您要跟蹤陣列中的空槽,以便它們可以被填滿,並且不要浪費 go。 以緊湊而有效的方式跟蹤空白空間的最佳方法是什么?

緊湊我的意思是,不是將每個刪除的索引存儲在另一個數組中,它應該存儲刪除的索引和該索引之后可用的插槽大小。 如果不使用 hash 表,它如何有效地做到這一點?

例如:

// step 1
[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] // added

// step 2..n eventually lands us to:
[a, -, -, d, e, f, -, -, -, -, -, l, -, n, -, p] // added
[-, b, c, -, -, -, g, h, i, j, k, -, m, -, o, -] // removed

// then compacted, the removed array would look more like:
[1:2,6:5,12:1,14:1] // removed

實現這個的算法是什么樣的?

let array1 = [] // added/items array
let array2 = [] // removed/free array

function removeFromArray1Naive1(index) {
  array1[index] = null
  array2[index] = true
}

function removeFromArray1Naive2(index) {
  array1[index] = null
  array2.push(index)
}

function removeFromArray1MaybeBetter(index) {
  array1[index] = null
  // ?
}

最后,在添加和刪除一堆項目之后,添加的數組是空的,我們最終會得到這個刪除的數組:

[{ index: 0, count: 16 }] // or however many there were.

使用 hash 表,我什至認為您做不到。 任何想法如何做到這一點(即適應約束)?

鏈表會很緊湊,但要知道在哪里插入/增加新刪除的索引,您必須遍歷數組。 B+tree 可以通過平衡操作和壓縮來解決這個問題,但它可能需要大量的重寫。 不知道有沒有更好的。 基本上我希望水桶能適當地裝滿。

嗯...我想我們不關心刪除索引的順序,所以也許這會有所幫助。

如果有任何巧妙的技術可以稍微重構問題並做一些有趣的事情來解決整體目標,那也可以。 例如,如果您有桶並且只是將物品扔進一個粗桶中,然后再進行壓縮,等等。

隨着我使用findIndex的一個更改,您應該使用二進制搜索,下面似乎工作得很好(每個數組中的第一項是原始數組中的索引,第二項是空項的長度):

 let arr = Array.from(Array(1000).keys()) let removed = []; let remove = (index) => { arr[index] = null; // find the index of the first removed element > index const i = removed.findIndex(([i]) => i > index); if (i === -1) { // there is no element greater, first check last element if (removed.length && removed[removed.length - 1][0] === index - 1) { removed[removed.length - 1][1]++; return } removed.push([index, 1]); return; } let [pos, length] = removed[i]; // if the next element greater than index is index + 1, // decrement it and increase the length if (pos === index + 1) { removed[i][0]--; removed[i][1]++; // if the previous element is equal to index - 1, merge them if (i > 0 && removed[i-1][0] === index - 1) { removed[i][0] -= removed[i-1][0]; removed[i][1] += removed[i-1][1]; removed.splice(i-1, 1); } return; } // if it's the first element, there is no previous, so we should just add it if (i === 0) { removed.unshift([index, 1]); return } [pos, length] = removed[i-1]; // pos and length are now the first element removed before this index if (pos === index - 1) { removed[i-1][1]++; } } remove(5); console.log(removed); remove(10); console.log(removed); remove(11); console.log(removed); remove(9); remove(1); console.log(removed)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM