LISP Упорядочивание списков вида ' ((a b) (c d) ... (x y))
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP Упорядочивание списков вида ' ((a b) (c d) ... (x y))

LISP Упорядочивание списков вида ' ((a b) (c d) ... (x y))

Ответ
Поиск в этой теме
Непрочитано 11.12.2009, 15:08 #1
LISP Упорядочивание списков вида ' ((a b) (c d) ... (x y))
Yurec
 
Регистрация: 11.12.2009
Сообщений: 2

Доброго времени суток уважаемым форумчанам!

Прошу помощи в реализации на LISPе такой задачи:

Есть список вида ' ((a b) (c d) ... (x y)). Значения элементов - целочисленные. Надо упорядочить его по убыванию сначала по первым элементам вложеных списков ( а , c , ..х).
Затем, если в полученном списке есть совпадающие значения первых элементов, упорядочить все подмножества ( с одинаковыми первыми элементами) по убыванию вторых элементов.

Заранее - премного благодарен за любую помощь
Просмотров: 5101
 
Непрочитано 11.12.2009, 15:24
#2
Елпанов Евгений

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


Код:
[Выделить все]
(setq l'((1 2)(3 3)(2 3)(4 4)(2 2)(1 1)))
(vl-sort l'(lambda(a b)(if (=(car a)(car b))(<=(cadr a)(cadr b))(<(car a)(car b)))))
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Автор темы   Непрочитано 11.12.2009, 15:29
#3
Yurec


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


Спасибо большое!!!
Работает! все супер!!
Yurec вне форума  
 
Непрочитано 11.12.2009, 16:31
#4
Sleekka

-
 
Регистрация: 24.07.2005
Москва
Сообщений: 1,335


удалил
Sleekka вне форума  
 
Непрочитано 25.05.2011, 11:28
#5
Ubivec81

проектирование железных дорог
 
Регистрация: 12.04.2010
Самара
Сообщений: 60
<phrase 1=


Может чуть не по теме но создавать новую не хочется.
Есть список типа ((a b) (c d) (e f)) . Функция (reverse) расставляет элементы в обратном порядке ((e f) (c d) (a b)), НО при (nth 0) все равно возвращает (a b). Можно это как то победить? Или может кто подскажет как добавлять элемент в список чтобы он становился не первым (cons)?
Ubivec81 вне форума  
 
Непрочитано 25.05.2011, 11:40
#6
Лиспер


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


Код:
[Выделить все]
 ; Вариант 1
(nth 0 (reverse '((a b) (c d) (e f))))
; Вариант 2
(car (reverse '((a b) (c d) (e f))))
; Вариант 3
(last '((a b) (c d) (e f)))
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 25.05.2011, 11:52
#7
Ubivec81

проектирование железных дорог
 
Регистрация: 12.04.2010
Самара
Сообщений: 60
<phrase 1=


Цитата:
Сообщение от Лиспер Посмотреть сообщение
Код:
[Выделить все]
 ; Вариант 1
(nth 0 (reverse '((a b) (c d) (e f))))
; Вариант 2
(car (reverse '((a b) (c d) (e f))))
; Вариант 3
(last '((a b) (c d) (e f)))
Спасибо. пробовал только первый вариант и он работает!
А можно тогда мне новенькому пояснить почему 1 вариант работает а
Код:
[Выделить все]
  (reverse '((a b) (c d) (e f))))
  (nth 0)
не работает???
И раз уж Вы откликнулись может подскажите как можно обращаться к конкретному элементу (я про то можно ли каждому элемента списка задать свое имя)?
Ubivec81 вне форума  
 
Непрочитано 25.05.2011, 12:07
#8
Дима_

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


1. У функции nth 2 аргумента - номер позиции и список - вы ее вызываете с одним.
2. Сугубо ИХМО - если в программе используется nth значит она хреново (с точки зрения лиспа) написана.
p.s. в лиспе не принято индексировать элемент списка через его адрес - для этого там есть свои методы - ассоциативные списки и пр. - список - это НЕИЗМЕНЯЕМАЯ структура (в отличие от массива).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 25.05.2011, 12:11
#9
Лиспер


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


К конкретному элементу можно обращаться по-разному: через nth, через assoc, еще несколько вариантов можно придумать... Все зависит от задачи.
> Дима_ : может, наоборот? Массив более-менее статичная структура, а список - весьма и весьма динамическая? Хотя, может, под структурой мы понимаем нечто разное?
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 25.05.2011, 12:14
#10
Дима_

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


то лиспер - скажите мне хоть одну функцию (или попробуйте написать сами) которая изменяет список?
п.с. - чтоб сразу было понятно - я сохраняю ссылку на список в переменной x (и еще нескольких) - покажите функцию которой можно передать x, а она изменит его (в том числе и во всех переменных).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 25.05.2011, 12:19
#11
Лиспер


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


Если коротко и без особого выпендрежа:
Код:
[Выделить все]
 (defun test (/ lst res1 res2)
  (setq lst  '((1 "a") (2 "b" "c") (3 "d") (4 "e"))
        res1 (subst (cons "2_1" (apply 'strcat (cdr (assoc 2 lst))))
                    (assoc 2 lst)
                    lst
                    ) ;_ end of subst
        res2 (cons (cons 10 "StartPoint") lst)
        ) ;_ end of setq
  (princ (strcat (vl-princ-to-string res1) "\n" (vl-princ-to-string res2)))
  (princ)
  ) ;_ end of defun
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 25.05.2011, 12:24
#12
Ubivec81

проектирование железных дорог
 
Регистрация: 12.04.2010
Самара
Сообщений: 60
<phrase 1=


Ну давайте тогда на примере:
Код:
[Выделить все]
 (defun c:kuvet ()
     (setq start (getreal"\nВведите пикет начала кювета - "))
     (setq finish (getreal"\nВведите пикет конца кювета - "))
     
     (setq dlina -1)
         
     (setq r ())
     
       (while (< dlina (- finish start))
         (setq q (list (setq X (getreal"\Пикет-")) (setq Y (getreal"\Отметка-"))))
          (setq r (cons q r))
          (setq dlina (1+ dlina))
       )
Я на данном этапе пытаюсь нарисовать профиль существующей земли, и создал список с элементами (X-пикет Y-отметка). В дальнейшем мне понадобиться в программе обратится к какому то пикету, чтобы получить точку существующей земли. можно ли каждому элементу списка присвоить имя X-пикет? Или же все придется делать перебором через (cond)?
Ubivec81 вне форума  
 
Непрочитано 25.05.2011, 12:26
#13
Дима_

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


то Ubivec81 почитай назначение функций assoc и subst
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 25.05.2011, 12:28
#14
Disney

Геодезист
 
Регистрация: 12.03.2009
Сибирь (где медведи по улицам ходят)
Сообщений: 860
Отправить сообщение для Disney с помощью Skype™


Ubivec81, функция никогда(на сколько мне известно) не изменяет свой аргумент, а лишь выполняет какое-то действие с ним, и чтобы использовать результат функции в дальнейшем не однократно, надо этот результат куда-нибудь записать, например в переменную, т.е.
Код:
[Выделить все]
 _$ (setq a '((a b) (c d) (e f)))
((A B) (C D) (E F))
_$ (reverse a)
((E F) (C D) (A B))
_$ a
((A B) (C D) (E F))
_$ (setq b (reverse a))
((E F) (C D) (A B))
_$ a
((A B) (C D) (E F))
_$ b
((E F) (C D) (A B))
_$ (nth 0 a)
(A B)
_$ (nth 0 b)
(E F)
_$ 
либо в случаи однократного использования результата какой-либо функции, то используем эту функцию(её результат) в качестве аргумента другой функции, как в 1 и 2 вариантах Лиспера
__________________
Почему все вдруг становятся умными, когда уже не надо?
Disney вне форума  
 
Непрочитано 25.05.2011, 12:32
#15
Лиспер


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


Disney, строго говоря, это возможно, если использовать вместо setq не менее интересную set Мне так каэцца Правда, я с подобным игрался очень давно. Ну и про рекурсию тоже вспоминается с особой теплотой.
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 25.05.2011, 12:33
#16
Ubivec81

проектирование железных дорог
 
Регистрация: 12.04.2010
Самара
Сообщений: 60
<phrase 1=


Цитата:
assoc <элемент списка> <структурированный список>)

Функция просматривает <структурированный список> по ключу <элемент списка> и возвращает точку входа <структур. списка>. Если <элемент списка> не найден, ASSOC возвращает nil. Например допустим, что "al" определен как:

((name box) (width 3) (size 4.7263) (depth 5))

тогда:

(assoc 'size al) возвращает (SIZE 4.7363)

(assoc 'weight al) возвращает nil

Структурированные списки часто используются для хранения данных, к которым можно иметь доступ по ключу. Это похоже на структуры и массивы в других языках программирования. Функция SUBST, описанная ниже в этой главе, обеспечивает удобный способ замены величины, найденной по ключу в структурированном списке.
Тут ника не допру что у меня есть ключ????
Или все же если писать в дальнейшем
Код:
[Выделить все]
 (setq PP (getreal"\nВВедите пикет для проектирования-"))
(assoc 'PP r)
отдаст мне то что мне нужно так как одинаковых пикетов не бывает?

Последний раз редактировалось Ubivec81, 25.05.2011 в 12:40.
Ubivec81 вне форума  
 
Непрочитано 25.05.2011, 12:35
#17
Лиспер


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


Любой список состоит из элементов. Если эти элементы в свою очередь списки, то их первые элементы являются ключами для "родителя".
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 25.05.2011, 12:38
#18
Дима_

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


Цитата:
Сообщение от Лиспер Посмотреть сообщение
Disney, строго говоря, это возможно
Я считаю Вы заблуждаетесь - возможно лишь затереть определенное имя и назначить ему новое значение (что через setq, что через set). С удовольствием посмотрю опровержение в виде кода из #10.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 25.05.2011, 12:48
#19
Ubivec81

проектирование железных дорог
 
Регистрация: 12.04.2010
Самара
Сообщений: 60
<phrase 1=


Ну да! с этим я разобрался! Спасибо господа!!!
Тогда может еще подскажите как в моем коде сделать цикл создания списка без
Код:
[Выделить все]
(setq start (getreal"\nВведите пикет начала кювета - "))
	    (setq finish (getreal"\nВведите пикет конца кювета - "))
	    (setq dlina -1)
а то я 2 дня думал но так и сделал только этот. Хотел сделать прерывание по пустому вводу но у меня не получилось....(наверна ОПЫТА маловато)
Ubivec81 вне форума  
 
Непрочитано 25.05.2011, 13:39
1 | #20
Disney

Геодезист
 
Регистрация: 12.03.2009
Сибирь (где медведи по улицам ходят)
Сообщений: 860
Отправить сообщение для Disney с помощью Skype™


Цитата:
Сообщение от Ubivec81 Посмотреть сообщение
прерывание по пустому вводу
Код:
[Выделить все]
 (setq start
       (getint "\nВведите пикет начала кювета - "
       )
)
(while (setq level
	      (getreal (strcat "\nВведите отметку ПК-"
			       (itoa start)
			       " :"
		       )
	      )
       )
  (setq	r     (cons (list start level) r)
	start (1+ start)
  )
)
__________________
Почему все вдруг становятся умными, когда уже не надо?
Disney вне форума  
 
Непрочитано 25.05.2011, 14:06
#21
Ubivec81

проектирование железных дорог
 
Регистрация: 12.04.2010
Самара
Сообщений: 60
<phrase 1=


Disney,
Код:
[Выделить все]
 
	(setq start
	       (getint "\nВведите пикет начала кювета - "
	       )
	)
	(while (setq level
	          (getreal (strcat "\nВведите отметку ПК-"
	                   (itoa start)
	                   " :"
	               )
	          )
	       )
	  (setq r     (cons (list start level) r)
	    start (1+ start)
	  )
	)

Можно перевести как это работает! че то я не понимаю.....
Ubivec81 вне форума  
 
Непрочитано 25.05.2011, 19:44
#22
Disney

Геодезист
 
Регистрация: 12.03.2009
Сибирь (где медведи по улицам ходят)
Сообщений: 860
Отправить сообщение для Disney с помощью Skype™


Цитата:
Сообщение от Ubivec81 Посмотреть сообщение
Можно перевести как это работает! че то я не понимаю.....
Вот, как мог расписал
Код:
[Выделить все]
 (setq start				     ;В переменную start записываем
       (getint				     ;введённое пользователя целое число
	 "\nВведите пикет начала кювета: "   ;служащее начальным пикетом
       ) ;_ _end_ofgetint
) ;_ _end_ofsetq
(while					     ;Пока
  (setq	level				     ;в переменную level будет записываться 
	 (getreal			     ;введённое пользователем вещественное число
	   (strcat			     ;на запрос собранный из 3 строк в одну:
	     "\nВведите отметку ПК-"	     ;первая строка
	     (itoa start)		     ;преобразовываем целое число(номер пикета) в строку
	     " :"			     ;третья строка
	   ) ;_ end of strcat
	 ) ;_ end of getreal
  ) ;_ end of setq
   (setq r				     ;в переменную r будем записывать
	       (cons			     ;список, полученный путём добавления в качестве первого элемента
		 (list start level)	     ;список, из двух элементов: 1-ый - номер пикета, 2-ой - отметка
		 r			     ;к ранее сформированному списку 
	       ) ;_ end of cons
	 start				     ;в переменную start записываем
	       (1+ start)		     ;номер следующего пикета
   ) ;_ end of setq
) ;_ end of while
__________________
Почему все вдруг становятся умными, когда уже не надо?
Disney вне форума  
 
Непрочитано 26.05.2011, 07:45
#23
Ubivec81

проектирование железных дорог
 
Регистрация: 12.04.2010
Самара
Сообщений: 60
<phrase 1=


Disney, Еще раз спасибо! Такое решение я бы сам наверна не скоро додумал.... Вот только в нем не получится наверное если пикет будет не целый. Хотя я еще поразбираю это все!
Ubivec81 вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP Упорядочивание списков вида ' ((a b) (c d) ... (x y))



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Запуск Lisp команды в новом документе BlackHarp LISP 1 26.03.2009 23:06
АА2008 Перенос вида на лист xag Вертикальные решения на базе AutoCAD 7 12.11.2008 11:47
LISP на _purge Малюк LISP 12 23.12.2007 18:15
Подшивки,блок идентификатор,марка вида wtl® AutoCAD 5 18.10.2006 23:20
загрузка DOS прог через LISP Gaa LISP 15 12.08.2005 19:19