Предложение представляется строкой и состоит из слов, разделённых пробелами, знаками горизонтальной табуляции или перевода строки. Возможно больше одного пробела между двумя словами.
Запятая, точка и другие знаки препинания считаются частью слова!
Текст — список предложений.
(defun whitespace-char-p (char) (member char '(#\Space #\Tab #\Newline))) (defun word-list (string) ;; Разбить строки на слова, разделённые знаками whitespace ;; A la (split-seq-if #'whitespace-char-p string) (loop with len = (length string) for left = 0 then (1+ right) for right = (or (position-if #'whitespace-char-p string :start left) len) unless (= right left) ; исключить пустые слова collect (subseq string left right) while (< right len))) (defun collect-word-counts (text) ;; Собрать все слова текста и подсчитать число их вхождений ;; Value: Хэш-таблица: слово -> счётчик (let ((ht (make-hash-table :test #'equal))) (dolist (sentence text) (dolist (word (word-list sentence)) ;; Отбросить знаки пунктуации справа от слов и к нижнему регистру (let ((string (string-right-trim ",.;:?!" (russian-string-downcase word)))) (when (< 0 (length string)) ; только непустые слова (incf (gethash string ht 0)))))) ht))