2015-06-04 3 views
2

У меня есть два заказанных набора Integer s - SortedSet<Integer>, назовите их set1 и set2. Мне нужно найти объединение этих множеств и вернуть ограничение смещения 10 подмножества 10. Что я имею в виду?Смещение и предел для набора

Set1: 
1,2,5,6,7,8,11,21,23,543,1002 

Set2: 
11,12,15,16,17,8,111,121,123,1543,11002 

Union: 
1,2,5,6,7,8,11,21,23,543,1002,12,15,16,17,111,121,123,1543,11002 

Union offset 10 limit 10: 
1002,12,15,16,17,111,121,123,1543,11002 

Обратите внимание, что из 8 кардинальность и 11 в союзе является 1.

Я ищу алгоритм, который позволяет мне не загружать все наборы в память (поскольку эти наборы могут быть довольно большими, я не буду тратить ресурсы сервера). Есть ли способ сделать это? Может быть, могут помочь некоторые мгновенные библиотеки, например commons или guava?

UPD: Я сам не использую Java 8, но решение, использующее его, также интересно.

+0

Вы не можете удалить дубликаты из set2 без загрузки set1 в память (или восстановить все значение set1 для каждого номера в set2, что, вероятно, очень неэффективно с точки зрения производительности) ... – assylias

+0

@assylias - Удаление дубликатов не является целью, это реализация. См. Мой ответ для «ленивого» подхода. – Amit

ответ

1

Алгоритм довольно прост.

 
Create empty hash 
Create empty array 
Set waste counter to 0 
Iterate all sets (2 or more) 
    Iterate set values 
    If value not in hash 
     Insert value into hash 
     Increase waste counter 
     If waste counter > offset (10) 
      Insert value into array 
      If array length == limit (10) 
      Done - return array 
+0

Спасибо, было бы более полезно, если бы вы переписали его на Java, а не в псевдокоде. – user3663882

+0

Кстати, насколько этот алгоритм более эффективен, чем полный serach? – user3663882

+0

Прошу прощения, я не использую java (как и вы :-), но вы просили алгоритм, а не реализацию – Amit

0

@ Ответ Амита хорош, но все еще может быть небольшой памятью неэффективно, если смещение также велико. Вот еще один подход:

Have a pointer on each set, 
while offset > 0: 
    if setA pointer value < setB pointer value 
     increment setA pointer 
     decrement offset 
    else 
     increment setB pointer 

add "limit" numbers starting from setA pointer to the output array. 
if end of setA is reached before "limit" numbers are present, 
    add the remaining numbers from setB pointer to the output array. 

Примечание: Это будет работать только на отсортированных наборах.
Дайте мне знать, если это неясно.

+0

Сборы образцов не сортируются. Это неправильно предположить. Кроме того, алгоритм не будет работать. Рассмотрим эти множества: A (10,11,12 ... 20), B (1,2,3 ... 10) со смещением (10) и пределом (10). Ваш алгоритм сначала выработает набор B, затем выдохнет, а затем сработает. – Amit

+0

@ Примите OP около 2 SortedSets. И в алгоритме я не включил все случаи краев, как то, что происходит, если наборы меньше смещения или предела (это всего лишь подход). – Codebender

+0

Вы правы, что OP упоминает SortedSets, но посмотрите на данные, они не отсортированы. Что касается «краевых случаев», их нет, есть 20 разных значений между двумя наборами, вы должны пропускать первые 10 и возвращать следующие 10 (установить B). Ваш алгоритм либо сбой, либо возврат 0 значений. И дело касается крайних случаев. Без них многие алгоритмы можно было бы улучшить несколькими факторами. – Amit

Смежные вопросы