Уменьшение использования памяти при хранении всех подпоследовательностей набора последовательностей

У меня есть набор входных последовательностей (представленных в виде списков), для каждой из которых я генерирую набор всех ее подпоследовательностей (также списки ). Эти подпоследовательности хранятся как ключи в хеш-таблице EQUAL и никогда не удаляются и не модифицируются сборщиком мусора (однако связанные значения изменяются).

Моя проблема в том, что метод, который я сейчас использую для достижения этой цели, использует гораздо больше места в куче, чем мне хотелось бы.

Чтобы было понятно, о чем я говорю, предположим, что у нас есть последовательность:

#1=(A B C D)

Подпоследовательности:

#2=()
#3=(A)
#4=(A B)
#5=(A B C)
#6=(A B C D)
#7=(B)
#8=(B C)
#9=(B C D)
#10=(C)
#11=(C D)
#12=(D)

Следующий код, который я признаю не очень хорошим, создает этот набор (за исключением пустого подпоследовательность, о которой я на самом деле не забочусь):

(defun subseqs-of-length (length sequence)
  (if (< (length sequence) length)
      nil
      (loop for start from 0 to (- (length sequence) length)
           collect (subseq sequence start (+ start length)))))

(defun subseqs-of-length-< (length sequence)
  (loop for len from 1 to (1- length)
     append (subseqs-of-length len sequence)))

(defun all-subseqs (sequence)
    (subseqs-of-length-< (1+ (length sequence)) sequence))

Как вы, вероятно, можете себе представить, при большом количестве входных последовательностей это занимает огромное количество кучи.

Самый очевидный способ сэкономить память, который я могу придумать, — это совместно использовать структуру списка; например, вы можете построить список 11 с помощью (cons 'c '#12#), список 9 с помощью (cons 'b '#11#), список 8 с помощью (cons 'b '#10#и т. д. Было бы еще лучше, если бы вывод нескольких вызовов all-subseqsмог совместно использовать структуру. Но я не могу придумать элегантного способа написать это.

У меня двоякий вопрос:

  1. Существует ли элегантный способ написать all-subseqs, чтобы его результаты имели такую ​​же структуру?
  2. Мне пришло в голову, что может быть проще сгенерировать подпоследовательности наивно и написать функцию для сжатия результатов и периодического запуска. Разве это не глупая идея?
  3. Есть ли еще более эффективный способ хранения этих подпоследовательностей и доступа/обновления связанных с ними значений? Возможно, что-то с использованием массивов или другой структуры данных вместо хеш-таблицы?
5
задан Samuel Edwin Ward 13 March 2012 в 22:41
поделиться