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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Как разобраться с непредсказуемой работой vl-sort?

Как разобраться с непредсказуемой работой vl-sort?

Ответ
Поиск в этой теме
Непрочитано 18.04.2019, 16:02 1 | #1
Как разобраться с непредсказуемой работой vl-sort?
Игорь Ч
 
Разработка
 
Москва
Регистрация: 18.04.2019
Сообщений: 3

Согласно описанию vl-sort при сортировке может удалять одинаковые значения, если они целые. В списке - длины, и одинаковые длины не должны удаляться . Т.е. (vl-sort '(2. 1. 3. 1.) '<)
(1.0 1.0 2.0 3.0)
Здесь тоже всё нормально:
(setq lst (append '(2.) '(2.) '(2.) '(1. 1.)))(vl-sort lst '<)
(2.0 2.0 2.0 1.0 1.0)
(1.0 1.0 2.0 2.0 2.0)
А здесь уже непонятно:
(setq two '(2.) lst (append two two two '(1. 1.)))(vl-sort lst '<)
(2.0 2.0 2.0 1.0 1.0)
(1.0 1.0 2.0)
Сортировка удалила 2 двойки!
Просмотров: 2428
 
Непрочитано 18.04.2019, 20:30
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


ИМХО vl-sort удаляет числа, совпадающие с некоторой точностью (скорее всего, до 16 значащих цифр). Правда, я в этом не сильно уверен
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 19.04.2019, 12:43
#3
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,665


Цитата:
Сообщение от Игорь Ч Посмотреть сообщение
с непредсказуемой работой vl-sort
работа vl-sort предсказуема.
если список составляется из переменных и чисел, vl-sort сортирует список учитывая имена переменныx, если таковые в списке есть и удаляет совпадения. на выходе отсортированный список со значениями переменных. удаляются совпадения атомов, символов, целых чисел, переменных

(setq one '(1))
(setq two '(2))
(setq four '(4.0))
(vl-sort (append two two two) '<) -> (2)
(vl-sort (append two two two one) '<) -> (1 2)
(vl-sort (append four four four two two two one one one one one '(0) '(3.0) '(3.0) '(3.0) four four) '<) -> (0 1 2 3.0 3.0 3.0 4.0)
koMon вне форума  
 
Непрочитано 19.04.2019, 13:25
#4
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


Цитата:
Сообщение от koMon Посмотреть сообщение
работа vl-sort предсказуема.
но нелогична - в других языках просто будут одинаковые элементы идти одной группой в списке друг за другом. А нельзя ли использовать функцию vl-sort-i ?
Цитата:
Duplicate elements will be retained in the result.
т.е. Аутодеск уверяет - что индексы дубликатов тоже будут возвращены.
Сергей812 вне форума  
 
Автор темы   Непрочитано 19.04.2019, 13:47
#5
Игорь Ч

Разработка
 
Регистрация: 18.04.2019
Москва
Сообщений: 3


Ну да. Отсюда следует, что интерпретатор должен "помнить" каким образом формировался список. Для одинаковых на внешний взгляд, но по-разному сформированных списков после vl-sort будет разный результат. В итоге пришлось подстраховаться функцией с использованием vl-sort-i:

(defun sort-safely (lst comparison-function / ilist sorted i)
(setq ilist (vl-sort-i lst comparison-function))
(setq sorted '())
(foreach i ilist (setq sorted (append sorted (list (nth i lst)))))
sorted
)
Игорь Ч вне форума  
 
Непрочитано 19.04.2019, 14:24
#6
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


Цитата:
Сообщение от Игорь Ч Посмотреть сообщение
Отсюда следует, что интерпретатор должен "помнить" каким образом формировался список.
А может vl-sort сначала вызывает vl-sort-i, а потом результат "прореживает" от дубликатов в цикле.
Сергей812 вне форума  
 
Непрочитано 19.04.2019, 14:30
#7
Sleekka

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


Цитата:
ИМХО vl-sort удаляет числа, совпадающие с некоторой точностью (скорее всего, до 16 значащих цифр). Правда, я в этом не сильно уверен
Как было отвечено выше совпадающие атомы, int, символы, и перемеенные (что тоже символы). У всего этого нет никакой точности при сравнении.

Подстраховка через vl-sort-i будет долго работать, т.к. вы делаете небыструю обертку вокруг.

Лучше сделать так (сначала привести сортируемые длины к real):
Код:
[Выделить все]
 
(defun sl-conv-value-to-string (value)


					; (sl-conv-value-to-string 123)	; "123"
					; (sl-conv-value-to-string 123.50)	; "123.5"
					; (sl-conv-value-to-string "qwer")	; "qwer"

  (cond
    ((not value) "")
    ((= (type value) 'str) value)
					; ((= (type value) 'real)(rtos value 2 15))
    (t (vl-princ-to-string value))
  ) ;_ end of cond
) ;_ end of defun


(defun to_re (value / )

(atof (sl-conv-value-to-string value))
	   
  )

(setq one 1)
(setq two 2)
(setq four 4.0)

(vl-sort (mapcar 'to_re (list two two two)) '(lambda (e1 e2) (< e1 e2)) )
(vl-sort (mapcar 'to_re (list four four four two two two one one one one one four four)) '(lambda (e1 e2) (< e1 e2)) )

И не формируйте списки 'append-ом, так вы будете долго возиться
Sleekka вне форума  
 
Непрочитано 19.04.2019, 14:44
#8
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,665


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
т.е. Аутодеск уверяет - что индексы дубликатов тоже будут возвращены.
да, но... индексы совпадений возвращаются в обращённом порядке

(vl-sort-i (append four four four two two two one one one one one '(0) '(3.0) '(3.0) '(3.0) four four) '<)

(11 10 9 8 7 6 5 4 3 14 13 12 16 15 2 1 0) - сортированные индексы
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16) - оригинальные индексы
koMon вне форума  
 
Непрочитано 19.04.2019, 15:30
#9
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


Цитата:
Сообщение от koMon Посмотреть сообщение
да, но... индексы совпадений возвращаются в обращённом порядке
ну они хотя бы возвращаются. А если посмотреть на vl-sort:
Цитата:
Duplicate elements may be eliminated from the list.
т.е. дубликаты могут быть удалены.. а что - могут быть и не удалены при каких то условиях? Разработчик сам не уверен в работе своей функции, или это плата за универсальность функции?

а для функции сортировки строк acad_strlsort вообще не говориться - как она с дубликатами работает.
Сергей812 вне форума  
 
Непрочитано 19.04.2019, 16:05
#10
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,665


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
Разработчик сам не уверен в работе своей функции, или это плата за универсальность функции?
кто-то помешал мануалрайтеру написать Duplicate elements may be are eliminated from the list. when they are atoms, symbols, integers...
koMon вне форума  
 
Непрочитано 19.04.2019, 16:13
#11
Sleekka

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


Используйте vl-sort только для real.
Либо используйте dos_sortnumbers в дополнение к предыдущему варианту (это для ленивых). Тест фукнцию типа 'lambda тоже можно здесь реализовать, но работает она медленнее, чем vl-sort
Код:
[Выделить все]
 
(setq one 1)
(setq two 2)
(setq four 4.0)

(vl-sort (mapcar 'to_re (list two two two)) '(lambda (e1 e2) (< e1 e2)) )
(vl-sort (mapcar 'to_re (list four four four two two two one one one one one four four)) '(lambda (e1 e2) (< e1 e2)) )

(dos_sortnumbers '(4 3 6 5 2 2 2 1 2 7 9 8))
(dos_sortnumbers (list four four four two two two one one one one one four four))
Sleekka вне форума  
 
Непрочитано 19.04.2019, 16:44
#12
Do$

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


Надо же, действительно, кривоватый метод!
Можно так обойти проблему:
Код:
[Выделить все]
(setq
  two '(2.)
  lst (mapcar (function (lambda (a) (* a 1.0))) (append two two two '(1. 1.))))
(vl-sort lst '<)
__________________
Толковый выбор приходит с опытом, а к нему приводит выбор бестолковый. (The Mechanic)
Do$ вне форума  
 
Автор темы   Непрочитано 19.04.2019, 17:44
#13
Игорь Ч

Разработка
 
Регистрация: 18.04.2019
Москва
Сообщений: 3


Цитата:
Сообщение от Do$ Посмотреть сообщение
Do$ Надо же, действительно, кривоватый метод!
Можно так обойти проблему:
(setq
two '(2.)
lst (mapcar (function (lambda (a) (* a 1.0))) (append two two two '(1. 1.))))
(vl-sort lst '<)
По количеству дополнительного кода, это наверное, самый короткий вариант:
(setq lst (mapcar (function (lambda (a) (* a 1.0))) lst)
"Отцепляет" список от того, что его породило.
Игорь Ч вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Как разобраться с непредсказуемой работой vl-sort?

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите разобраться с расчетом п/п как элементов висячей системы при прогрессирующем обрушении AAVik Железобетонные конструкции 0 09.02.2019 15:13
Помогите разобраться с проектированием и согласованием дорог KretininAS Автомобильные и железные дороги, мосты, тоннели и организация движения 19 14.08.2012 18:50
Помогите разобраться в расчёте металлических ферм в пространственной схеме в SCAD Stingry SCAD 9 04.01.2012 14:41
Помогите разобраться с конструкцией паровой турбины агрегата ТС-2 Vladimir757 Машиностроение 1 06.12.2011 21:49