LISP, нахождение самого длинного слова
Формулировка задачи:
Доброго времени суток!
Такой вопрос: нужно запрограммировать функцию, которая принимает на вход текст и возвращает длину самого длинного слова, состоящего из цифр и само это слово, если таковых несколько, то вернуть последнее.
Есть программа, которая выполняет данную задачу:
Однако она работает только, если ей на вход подаётся список, т.е.:
если: (max-length-number '(aaa bbb 55 42)), то всё верно (ответ: 2, 42)
если: (max-length-number '("aaa bbb 55 42")), то выдаёт (0, NIL) вместо 2, 42.
Подскажите пожалуйста как можно исправить, чтобы данная программа работала с текстом.
(defun max-length-number (w
&aux
(m (loop for a in w
when (numberp a) maximize
(length (write-to-string a)))))
(when m (list m (find-if
#'(lambda (a)
(and (numberp a)
(= (length (write-to-string a))
m)))
w :from-end t)))
)Решение задачи: «LISP, нахождение самого длинного слова»
textual
Листинг программы
(defun split (s &aux ac (m (make-string-output-stream))) (loop for a across s if (or (char= a #\Space) (char= a #\Tab) (char= a #\Newline)) do (push (get-output-stream-string m) ac) else do (write-char a m)) (push (get-output-stream-string m) ac) (nreverse ac)) (defun max-length (w &aux (m (loop for a in w when (all-digit-p a) maximize (length a)))) (when (and m (plusp m)) (list m (find-if #'(lambda (a) (and (all-digit-p a) (= (length a) m))) w :from-end t)))) (defun all-digit-p (s) (loop for c across s always (digit-char-p c))) (defun max-length-number (s) (max-length (split s))) > (max-length-number "aa 333 bb 555 77") (3 "555") > (max-length-number "77") (2 "77") > (max-length-number "aa") NIL > (max-length-number "") NIL
Объяснение кода листинга программы
- Находим самое длинное число в строке, состоящее только из цифр.
- В этой функции используется функция
all-digit-p, которая проверяет, состоит ли символ из цифр. - Функция
max-lengthвозвращает наибольшую длину числа из списка чисел. - В этой функции используется функция
find-if, которая ищет первый элемент, удовлетворяющий заданному условию. - В функции
all-digit-pиспользуется циклloopдля проверки каждого символа строки. - Функция
digit-char-pпроверяет, является ли символ цифрой. - Функция
max-length-numberвызывает функциюmax-lengthдля списка чисел, полученных с помощью функцииsplit. - В функции
splitиспользуется циклloopдля перебора каждого символа строки. - Если символ является пробелом, табуляцией или переводом строки, он добавляется в список.
- В конце функция
splitдобавляет в список строку, полученную из выходного потока. - Функция
get-output-stream-stringполучает строку из выходного потока. - Функция
pushдобавляет новый элемент в конец списка. - Функция
nreverseизменяет порядок элементов в списке, чтобы самые длинные числа были в начале. - Функция
loopиспользуется для перебора каждого числа в списке. - Если число является строкой, состоящей только из цифр, функция
lengthнаходит его длину. - Функция
max-lengthвозвращает наибольшую длину числа из списка чисел. - Если наибольшая длина не равна нулю, функция
find-ifищет первое число, длина которого равна максимальной длине. - Функция
listсоздает новый список из найденного числа и его длины. - Функция
splitвызывается для разделения строки на список чисел. - Функция
max-length-numberвызывается для нахождения самого длинного числа в строке.