Mam listę receptur uzyskano z bazy danych, która wygląda następująco:Jak wybrać losowy element tablicy, który odpowiada pewne kryteria w czasie O (1)
List<RecipeNode> _recipeList;
RecipeNode
, między innymi, ma właściwość, która odwołuje się jeden lub więcej znaczników (takich jak Kolacja, śniadanie, Side, Wegetariańska, wakacje i około 60 innych).
public sealed class RecipeNode
{
public Guid RecipeId;
public Byte[] Tags; //Tags such as 1, 5, 6, 8, 43
//... More stuff
}
Znalezienie losowy przepis z _recipeList
w czasie O (1) byłoby oczywiście łatwe, jednak to, co trzeba zrobić, to znaleźć losowy przepis, który ma, powiedzmy, 5 w Tags
w czasie O (1).
W tej chwili moim jedynym pomysłem jest utworzenie tablicy List<RecipeNodes>
, z kluczem. Na przykład:
List<RecipeNode>[] _recipeListByTag;
Następnie _recipeListByTag[5]
będzie zawierać listę wszystkich przepisów, które mają 5 w tablicy Tags
. Mógłbym wtedy wybrać losowy dozwolony znacznik i losową recepturę w tym znaczniku w O (1).
Wadą tego podejścia jest wielkość tej wielowymiarowej tablicy: Recipes * Tags
(np. Suma Tags.length dla wszystkich receptur), która zaczyna zajmować dużo pamięci, ponieważ przechowywam potencjalnie ogromny liczba receptur w tej tablicy. Oczywiście, ponieważ RecipeNode
jest typem referencyjnym, powtarzam tylko wskaźniki 4-bajtowe do receptur, więc to nadal może być najlepsza metoda.
Czy istnieje bardziej wydajna struktura danych lub algorytm, który mógłbym użyć, aby umożliwić mi znalezienie losowej receptury zawierającej określoną dozwoloną etykietę? Dzięki!
Dlaczego nie używać po prostu 'SQlite'? I odzyskaj dane w stałym (o ile to możliwe) czasie. – Tigran
+1 Tigran - wygląda na problem dostosowany do DB. – Oded
Wydaje mi się bardzo dziwne, że używasz tablicy bajtów dla znaczników, zamiast czegoś faktycznie zorientowanego obiektowo, takiego jak lista odwołań do obiektów znaczników. Czy naprawdę masz takie ograniczenia pamięci, że tak naprawdę musisz robić takie hacki? –