| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Библиотека функций > Функция "рекурсивирования" или рекурсивная lambda

Функция "рекурсивирования" или рекурсивная lambda

Ответ
Поиск в этой теме
Непрочитано 20.05.2010, 13:54 #1
Функция "рекурсивирования" или рекурсивная lambda
Дима_
 
Продуман
 
Питер
Регистрация: 22.02.2007
Сообщений: 2,840

Вот эта тема (а точнее оффтопное направление по поводу функций\операторов заданное уважаемым ShaggyDoc'ом) натолкнуло меня на мысль о возможности совместить две, одни из самых интересных, возможности LISP - рекурсия и lambda. Вот что из этого вышло:

Код:
[Выделить все]
(defun recurs (p f x);создает рекурсивный список до выполнения условия p функции f с начальным аргументом х
  (if (p x)
      (cons x nil)
      (cons x (recurs p f (f x)))))
При всей малости кода функции, по крайней мере лично для меня, она открывет "большие удобства" а именно - если внутри лямбды хочеться используеть рекурсии - то совсем не обязательно выводить их в новую функцию:
Пример1 - получить список от 0 до х (целое, положительное):
классика:
Код:
[Выделить все]
(defun test (x)
(if (zerop x) (cons x nil) (cons x (test (1- x)))))
(reverse (test 10))
аналог:
Код:
[Выделить все]
(reverse (recurs zerop 1- 10))
Пример2 (посложнее) - выровнять слово str пробелами с правой стороны до 10-ти символов:
классика:
Код:
[Выделить все]
(defun rovno (str)
(if (>=(strlen str) 10) str (rovno (strcat str " "))))
(rovno "test")
аналог:
Код:
[Выделить все]
(last (recurs (lambda (str) (>= (strlen str) 10)) (lambda (str) (strcat str " ")) "test"))
Количество кода в общем-то не уменьшается, но дает возможность использовать рекурсию внутри ламбды - не "засоряя" имена.
p.s. - немного подправил функцию - чтоб сохранял последний аргумент
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 20.05.2010 в 14:11.
Просмотров: 19380
 
Непрочитано 09.11.2013, 02:38
#2
SetQ

конструктор
 
Регистрация: 21.07.2007
Петрозаводск
Сообщений: 1,971


Попробовал написать факториал, что-то у меня уж совсем код разросся:

Код:
[Выделить все]
 (DeFun fact1  (x)
  (if (zerop x)
    1
    (* x (fact1 (1- x)))))

(DeFun fact2  (x)
  (caar
    (reverse
      (recurs (lambda (x) (zerop (cdr x)))
	      (lambda (x) (cons (* (car x) (cdr x)) (1- (cdr x))))
	      (cons 1 x)))))
Наверное, можно как-то короче.
SetQ на форуме  
 
Автор темы   Непрочитано 10.11.2013, 23:35
#3
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Так или эдак - по размеру почти байт в байт:
Код:
[Выделить все]
 (defun fact3(x)
  (apply '* (recurs (lambda (x) (= x 1)) 1- x)))
(defun fact4(x)
  (apply '* (cdr (reverse (recurs zerop 1- x)))))
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 23.12.2014, 18:50
#4
unfold


 
Регистрация: 23.12.2014
Сообщений: 1


Поздравляю, вы почти изобрели функцию unfold из Scheme.
Вот вам ее итеративная (для отважных, в комментарии - рекурсивная) реализация на AutoLISP.
Код:
[Выделить все]
 
;;; unfold p f g seed => result-list
;;; p - determines when to stop unfolding.
;;; f - maps each seed value to the corresponding list element.
;;; g - maps each seed value to next seed value.
;;; seed - the state value for the unfold.
;;; (defun unfold (p f g seed)
;;;   (if (not (apply p (list seed)))
;;;       (cons (apply f (list seed))
;;;             (unfold p f g (apply g (list seed))))))
;;; Fundamental list constructor.
;;; (unfold (function (lambda (x) (> x 10))) 'sqr '1+ 1)
;;; => (1 4 9 16 25 36 49 64 81 100)
(defun unfold (p f g seed / lst)
  (while (not (apply p (list seed)))
    (setq lst (cons (apply f (list seed)) lst)
          seed (apply g (list seed))))
  (reverse lst))
unfold вне форума  
 
Непрочитано 12.04.2015, 19:03
#5
Веселин


 
Регистрация: 15.05.2014
Сообщений: 42


Ничего не понял. Так есть в Autolisp пространство имён или нет?
Веселин вне форума  
 
Автор темы   Непрочитано 12.04.2015, 22:33
1 | #6
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Я в общем тоже не понял - при чемздесь эта тема и пространства имен - но по сути вопроса - в автолиспе их нет - ни в лисп смысле, не в смысле императивных язвыков - эти омонимы сильно различаются, в автолиспе есть только локализированные имена.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 26.04.2015, 02:58
#7
kakt00z

инженер-проектировщик КИПиА
 
Регистрация: 30.08.2008
Минск
Сообщений: 159


просто unfold построил еще и 3-й этаж (думаю Дима_ - прото не успел) )))
но это всеравно не идет ни в какое сравнение с шедеврами :
1. (apply 'mapcar (cons 'list[list]))
2. была гдето функция concat вродебы для слияния двух списков вроде даж Димы_
а это - частный, зачастую реализуемый 1-2 раза в решении, и короче, интерфейс (! ИМХО)
kakt00z вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Библиотека функций > Функция "рекурсивирования" или рекурсивная lambda

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Вставка в таблицу поля, соотвествующего площади примитива Profan Готовые программы 272 06.06.2021 23:12
Определение количества используемой памяти. solo123 Программирование 8 22.03.2010 14:32
(GRREAD) и привязка Ева Программирование 17 18.12.2009 09:10
Копирование данных для спецификаций из выносок СПДС в таблицу из мтекстов Red Nova Программирование 177 08.12.2008 11:35