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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Помогите со списком Lisp

Помогите со списком Lisp

Ответ
Поиск в этой теме
Непрочитано 28.10.2010, 11:08 #1
Помогите со списком Lisp
Mozgunov
 
Начинающий проектировщик
 
Санкт-Петербург
Регистрация: 07.02.2008
Сообщений: 443

Ребят подскажите как можно сделать вот такую штуку. Есть список типа
Код:
[Выделить все]
((тип1 значение) (тип2 значение) (тип1 значение) (тип 3 значение))
Как получить список типа:
Код:
[Выделить все]
((тип1 суммарное_значение_типа_1) (тип2 суммарное_значение_типа_2) (тип3 суммарное_значение_типа_3))
Пример может есть какой? Спасибо!
Просмотров: 3185
 
Непрочитано 28.10.2010, 11:32
#2
TararykovDG

Программист-энтузиаст
 
Регистрация: 17.07.2009
Воронеж
Сообщений: 575


Mozgunov, попробуй так

Код:
[Выделить все]
(defun sum_lst(lst / )
  (if lst
    (cons
      (list (caar lst) (apply '+ (mapcar 'cadr (vl-remove-if-not '(lambda(x) (= (car x) (caar lst))) lst))))
      (sum_lst (vl-remove-if '(lambda(x) (= (car x) (caar lst))) lst))
      )
    )
  )

Пример:
_$ (setq lst (list (list "t1" 2) (list "t2" 5) (list "t1" 3) (list "t3" 7) (list "t1" 10) (list "t2" 3) (list "t3" 1)))
(("t1" 2) ("t2" 5) ("t1" 3) ("t3" 7) ("t1" 10) ("t2" 3) ("t3" 1))
_$ (sum_lst lst)
(("t1" 15) ("t2" 8) ("t3" 8))
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 28.10.2010, 11:51
#3
Mozgunov

Начинающий проектировщик
 
Регистрация: 07.02.2008
Санкт-Петербург
Сообщений: 443
<phrase 1=


TararykovDG, Спасибо большое! Всё работает. Сейчас буду разбираться что к чему.
Mozgunov вне форума  
 
Непрочитано 28.10.2010, 12:22
#4
Лиспер


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


Вариант без рекурсии и побыстрее:
Код:
[Выделить все]
(setq key_lst '(("key1" 1) ("key2" 2) ("key1" -10.) ("t1" 10)))
(defun sum_test (lst / res)
  (foreach item lst
    (setq res
           (cond
             ((member (car item) (mapcar (function car) res))
              (subst (list (car item)
                           (+ (cadr item) (cadr (assoc (car item) res)))
                           ) ;_ end of list
                     (assoc (car item) res)
                     res
                     ) ;_ end of subst
              )
             (t (cons item res))
             ) ;_ end of cond
          ) ;_ end of setq
    ) ;_ end of foreach
  res
  ) ;_ end of defun
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 28.10.2010, 12:39
#5
Дима_

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


Цитата:
Сообщение от Лиспер Посмотреть сообщение
Вариант без рекурсии и побыстрее:
Насчет быстрее тут совсем не однозначно...
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 28.10.2010, 12:41
#6
Лиспер


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


Я проверял на коротких списках. Чем список длиннее, тем, конечно, результаты будут неоднозначнее.
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Автор темы   Непрочитано 29.10.2010, 09:36
#7
Mozgunov

Начинающий проектировщик
 
Регистрация: 07.02.2008
Санкт-Петербург
Сообщений: 443
<phrase 1=


Спасибо. У меня в списке 50-70 элементов. Поэтому первый вариант вполне годится! Скорость выполнения не критична.
Mozgunov вне форума  
 
Непрочитано 15.02.2011, 23:24
#8
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Чет я совсем туплю...
Нужно развернуть список и все его подсписки...
придумал такого динозавра...
Код:
[Выделить все]
 (defun reverse-tree (tree)
  (if (listp tree)
    (reverse
      ((setq
	 f-rec
	  (lambda (tree)
	    (mapcar
	      '(lambda (node)
		 (if (atom node)
		   node
		   (f-rec (reverse node))
		 )
	       )
	      tree
	    )
	  )
       )
	tree
      )
    )
    tree
  )
)
а как без лямбды
gomer вне форума  
 
Непрочитано 16.02.2011, 09:09
#9
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,701
Отправить сообщение для Do$ с помощью Skype™


Вот так получилось:
Код:
[Выделить все]
 (defun reverse-tree (lst)
  ;;(reverse-tree '("1" "2" "3" "4" ("5" "6" "7" "8") "9" "10" (("10.0" "10.1" "10.2" ("10.2.1" "10.2.2" "10.2.3" "10.2.4") "10.3") "11" "12" "13" "14")))
  (if lst
    (reverse
      (cons (if (listp (car lst))
       (reverse-tree (car lst))
       (car lst)
     ) ;_ end of if
     (reverse (reverse-tree (cdr lst)))
      ) ;_ end of cons
    ) ;_ end of reverse
  ) ;_ end of if
) ;_ end of defun

Последний раз редактировалось Do$, 16.02.2011 в 10:44. Причина: вместо append - 2 reverse и cons
Do$ вне форума  
 
Непрочитано 16.02.2011, 10:41
#10
Дима_

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


To Gomer - что я вижу у Вас появилась f-rec! Самое интересное - что эту задачу я бы предпочел решить mapcarom:
Код:
[Выделить все]
 (defun reverse-tree (lst)
(mapcar '(lambda (x)
           (if (listp x)
               (reverse-tree x)
               x))
        (reverse lst)))
P.S. кстати во всех трех кодах есть на первый раз незаметная логическая ошибка - кто видит какая?
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 16.02.2011 в 10:46.
Дима_ вне форума  
 
Непрочитано 16.02.2011, 19:25
#11
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Дима_ Посмотреть сообщение
To Gomer - что я вижу у Вас появилась f-rec! Самое интересное - что эту задачу я бы предпочел решить mapcarom:
тю, я знал, что все так просто... Но, как ни крутил... так и не додумался...
Дима_, если эта f-rec не появилась бы, то было бы моего вопроса...
Задание, которое я решал было:
Цитата:
Реализовать функцию, которая в исходном списке заменяет все элементы-списки результатами их реверсирования. Реверсирование производить на всех уровнях вложения. Пример: для списка ‘(1 ((2 3) 4) 5 6) результатом будет : ‘(1 (4 (3 2)) 5 6).
получилась такая функция:
Код:
[Выделить все]
 (defun reverse-tree (tree)
  (mapcar
    '(lambda (node)
       (if (atom node)
	 node
	 (reverse-tree (reverse node))
       )
     )
     tree
  )
)
Естественно я подумал: почему верхний уровень не реверсируется...
Нутром почуял ошибку...
Дима_,
Но что же за ошибка, в кодах???
gomer вне форума  
 
Непрочитано 16.02.2011, 20:11
#12
Дима_

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


Цитата:
Сообщение от gomer Посмотреть сообщение
Но что же за ошибка, в кодах???
Она не столько в кодах - сколько в особенности автолиспа попробуй выполнить (reverse-tree (entget (entlast))) - в любой версии reverse-tree.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 16.02.2011, 20:52
#13
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Дима_ Посмотреть сообщение
попробуй выполнить (reverse-tree (entget (entlast)))
А можно подробнее? Подозреваю, что выпендреж vl из за точечных пар...
gomer вне форума  
 
Непрочитано 16.02.2011, 22:12
#14
Дима_

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


формально список - это последовательность точечных пар заканчивающихся nil (он же '()) - но функция listp - определяет его за "своего" - хотя формально он таким не является - нельзя применить "списочную" фунцию (mapcar, append и пр.) к (cons 1 1) или (cons 1 (cons 1 1)), atom в свою очередь тоже его "своим" не признает - то есть для реализации с любым списком неплохобы "забацать" какой-нибудь consp и решить - надо ли менять пару местами.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 17.02.2011, 10:49
#15
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


у меня получилось:
Код:
[Выделить все]
 (defun f (l)
 (if (atom l) l
  (reverse (mapcar 'f l))
 )
)
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 17.02.2011, 11:22
#16
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,701
Отправить сообщение для Do$ с помощью Skype™


Цитата:
Сообщение от Елпанов Евгений Посмотреть сообщение
у меня получилось:
Код:
[Выделить все]
 (defun f (l)
 (if (atom l) l
  (reverse (mapcar 'f l))
 )
)
Браво, Евгений!
Do$ вне форума  
 
Непрочитано 17.02.2011, 19:03
#17
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Все, я понял...
Вот что я искал...
Код:
[Выделить все]
 (defun reverse-tree (tree)
  (if (atom tree)
    tree
    (mapcar 'reverse-tree (reverse tree))
  )
)
Елпанов Евгений, вам самое большое: thank_you:
gomer вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Помогите со списком Lisp



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
lisp помогите обработать список Apelsinov LISP 33 16.07.2021 15:56
помогите поправить программку на lisp gizmo_zx LISP 12 16.09.2010 17:21
Auto Lisp. Помогите с легкой программой. BARS_1985 LISP 6 27.09.2007 11:10
LISP помогите разобраться. Elenaka LISP 5 20.10.2006 18:15
Помогите отладить lisp программу Мишаня LISP 7 31.07.2006 12:54