2017-07-21 88 views
3

我有一個項目列表,每個項目都有一個與它相關的排名。在不改變所有項目的排名的情況下排列項目

Item 1, Rank=1 
Item 2, Rank=2 
Item 3, Rank=3 
Item 4, Rank=4 
Item 5, Rank=5 

我想設計用來處理以最小的項目或其他項目的隊伍沒有變化的重新排序的方法。

我想到的一個解決方案是利用小數點並使用Java的雙變量類型。因此,舉例來說,如果我移動ITEM5 ITEM2和項目3之間,這將是輸出 -

Item 1, Rank=1 
Item 2, Rank=2 
Item 5, Rank=2.5 
Item 3, Rank=3 
Item 4, Rank=4 

等等,

Item 1, Rank=1 
Item 2, Rank=2 
Item 4, Rank=2.25 
Item 5, Rank=2.5 
Item 3, Rank=3 

此解決方案的工作,但之後的某一點(〜55個在移動相同的位置,我達到雙變量限制,我可能不得不重置所有級別在那一點)

我只是想知道是否有一些更好的方法來解決這個問題?

有幾件事要記住。

  • 我需要這個數據結構存儲在數據庫中(項目,排名),我將建立一個Web服務,它獲得所有項目的基礎上排名的排序順序,所以我將作出一個數據庫調用get所有項目按排名字段排序。
  • 我將使用Java,因此我只能處理Java變量。
+0

看看https://github.com/mixonic/ranked-model - 我知道這是ruby/rails而不是java,但是你可以看看它們的實現並記下一些註釋。他們在等級之間使用非常大的空間來實現他們能夠在不改變整個等級的情況下改變事物的目標。 – PressingOnAlways

+0

你使用什麼數據結構?鏈接列表允許將O(1)插入到列表中,一旦迭代到所需的索引。然後,您可以使用列表中項目的結構位置來指示排名。 – 4castle

+0

我其實也想到了這個解決方案。但是,我會再擴大我的範圍,並在稍後的時間達到極限。感謝您將我指向github,但是:) :) –

回答

2

如何編寫一個小例程,它將數組元素的排列值均勻分佈在數組(或列表或其他)中?

如果在位置x處插入新元素,則將範圍x-1 .. x+1的元素傳遞到子例程中。在開始和結束位置的等級值保持不變,其他均以均勻的距離計算。如果成功,則返回true。現在,如果距離太小,則返回false,調用者將範圍擴展到x-2 .. x+2,並再次進入子例程。

你不得不小心撞到陣列邊界,甚至完全沒有價值空間。

2

有可能是多種解決方案,這裏是一個我喜歡

我想分裂這個問題分成多個隔離的1:

  1. 在Java後端你想擁有列表的項目,以某種方式排序,有可能按順序快速O(1)變化。

最好的結構 - 雙鏈表。您將需要使用散列表快速在此列表中按項目名稱/ ID查找對象。

您可以很容易地將這樣的結構存儲到數據庫中,只需在項目表中添加兩個外鍵即可。在存儲過程中,您只需更新受影響的行(請記住,移動項目時,前/後項目也會受到影響)。它看起來像多個update table set prev=?, next=? where id=?

  1. 在您的java服務中,您希望儘可能快地顯示排序的項目列表,可能是分頁的。

最好的結構 - 預先排序的數組。

要將這樣的結構存儲在數據庫中,您需要存儲位置的列(級別)。當然你需要在這個專欄上索引。

要檢索這樣的結構,您將使用非常簡單,快速和高效的查詢,如select item from table order by rank limit ?,?


現在你有矛盾,爲編輯您的數據結構不匹配檢索和使用單個數據結構這兩個問題會導致性能下降的一個部分的任何企圖你的數據結構,允許獨立解決這個問題:

  1. 您將創建單獨的異步服務(cron作業),它將讀取一個表中的數據,轉換(重新計算所有項目的排名)並存儲在另一個表中。

在這裏,您將有兩個選擇:在計算或完全替換第二個表中的數據或找到差異並僅更新已更改的行。我相信完全替代更容易實現,實際上它可能更快。

因此,通過這種方法,您的系統的客戶可見部分執行得非常好(數據管理部分和數據顯示部分的工作速度儘可能快)。

唯一的問題是改變傳播,這通常很好,大多數用戶會接受它作爲合理的權衡。

相關問題