;;;;; ;; Very easy but inefficient (defvar *words* (make-hash-table)) (defun add-word (word type) (push word (gethash type *words*))) (defun process (line) (loop with word = NIL for i from 0 below (length line) for char = (aref line i) do (cond ((eql char #\MULTIPLICATION_SIGN) (setf word (subseq line 0 i))) (word (add-word word char))))) (defun process-stream (stream) (loop for line = (read-line stream NIL NIL) while line do (process line))) (defun process-file (pathname &key (if-does-not-exist :error)) (with-open-file (stream pathname :if-does-not-exist if-does-not-exist) (process-stream stream))) ;;;;; ;; Now the same, but with vectors. (defvar *words* (make-hash-table)) (defun ensure-word-vector (type) (or (gethash type *words*) (setf (gethash type *words*) (make-array 0 :adjustable T :fill-pointer T)))) (defun add-word (word type) (vector-push-extend word (ensure-word-vector type))) ;; rest stays the same ;;;;; ;; Now the same but with a vector instead of words list. (defvar *words* (make-array (char-code #\z))) (defun words (type) (aref *words* (char-code type))) (defun (setf words) (vector type) (setf (aref *words* (char-code type)) vector)) (defun ensure-word-vector (type) (or (words type) (setf (words type) (make-array 0 :adjustable T :fill-pointer T)))) ;; rest stays the same ;;; Personally I would go with the hash-table+vector solution.