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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Сортирвка списка последовательно, по приоритетам (вопрос)

Сортирвка списка последовательно, по приоритетам (вопрос)

Ответ
Поиск в этой теме
Непрочитано 02.02.2010, 10:31 #1
Сортирвка списка последовательно, по приоритетам (вопрос)
Tonic
 
Воронеж
Регистрация: 26.06.2007
Сообщений: 151

Столкнулся вот с такой задачкой по сортировке: AutoCAD меня понял, Bricscad - не захотел. Может, я что-то не правильно делаю?

Имеется массив различных блоков (рис. 1). Я получаю список следующего вида:

Код:
[Выделить все]
((<Имя объекта: 7ef89d48> "СК5-40н" (104276.0 6743.88 0.0))
(<Имя объекта: 7ef89d40> "СК5-40н" (104865.0 6743.88 0.0))
(<Имя объекта: 7ef89d38> "СК5-40н" (104276.0 7470.11 0.0))
(<Имя объекта: 7ef89d30> "СК5-40н" (104865.0 7470.11 0.0))
(<Имя объекта: 7ef89818> "СНпр3-30" (102868.0 6173.29 0.0))
(<Имя объекта: 7ef89810> "СНпр3-30" (104986.0 6173.29 0.0))
(<Имя объекта: 7ef89808> "СНпр3-30" (105659.0 6173.29 0.0))
(<Имя объекта: 7ef89800> "СНпр3-30" (104263.0 6173.29 0.0))
(<Имя объекта: 7ef897b8> "СНпр3-30" (103541.0 6173.29 0.0))
(<Имя объекта: 7ef897a0> "СК5-40н" (102967.0 8098.84 0.0))
(<Имя объекта: 7ef89798> "СК5-40н" (103556.0 8098.84 0.0))
(<Имя объекта: 7ef89770> "СНпр3-30" (101705.0 6532.29 0.0))
(<Имя объекта: 7ef89768> "СНпр3-30" (101705.0 7154.83 0.0))
(<Имя объекта: 7ef89760> "СНпр3-30" (102379.0 6532.29 0.0))
(<Имя объекта: 7ef89758> "СНпр3-30" (102379.0 7154.83 0.0))
(<Имя объекта: 7ef89750> "СНпр3-30" (102917.0 6864.31 0.0))
(<Имя объекта: 7ef89748> "СНпр3-30" (102917.0 7486.85 0.0))
(<Имя объекта: 7ef89740> "СНпр3-30" (103591.0 6864.31 0.0))
(<Имя объекта: 7ef89738> "СНпр3-30" (103591.0 7486.85 0.0))
(<Имя объекта: 7ef89720> "СНпр3-30" (104186.0 8102.8 0.0))
(<Имя объекта: 7ef89708> "СНпр3-30" (106304.0 6754.03 0.0))
(<Имя объекта: 7ef89700> "СНпр3-30" (106304.0 7376.57 0.0))
(<Имя объекта: 7ef896f0> "СНпр3-30" (106977.0 6754.03 0.0))
(<Имя объекта: 7ef896e8> "СНпр3-30" (106977.0 7376.57 0.0))
(<Имя объекта: 7ef896e0> "СНпр3-30" (106977.0 8102.8 0.0))
(<Имя объекта: 7ef896c8> "СНпр3-30" (105582.0 6754.03 0.0))
(<Имя объекта: 7ef896c0> "СНпр3-30" (105582.0 7376.57 0.0))
(<Имя объекта: 7ef89698> "СК5-40н" (104981.0 8292.79 0.0))
(<Имя объекта: 7ef89690> "СК5-40н" (105503.0 8292.79 0.0))
(<Имя объекта: 7ef89688> "СК5-40н" (106092.0 8292.79 0.0)))
Теперь мне надо пронумеровать блоки так, как указано на рис.2. (слева направо снизу вверх с учётом принадлежности к группе (по строке))
Для этого я последовательно сортирую изначальный список (назовём его test_list):


Код:
[Выделить все]
  ;Сортировка списка по названию блока:
(setq test_list
       (vl-sort
	 test_list
	 (function (lambda (x1 x2) (< (nth 1 x1) (nth 1 x2))))
       )
)

  ;Сортировка списка по координате Y с учётом предыдущей сортировки (при условии, что сопоставляются одинаковые наименования блоков!):
(setq test_list
       (vl-sort
	 test_list
	 (function (lambda (x1 x2)
		     (AND
		       (equal (nth 1 x1) (nth 1 x2))
		       (< (nth 0 (nth 2 x1)) (nth 0 (nth 2 x2)))
		     )
		   )
	 )
       )
)
  
  ;Сортировка списка по координате X с учётом предыдущей сортировки (при условии, что сопоставляются одинаковые виды свай):
(setq test_list
       (vl-sort
	 test_list
	 (function (lambda (x1 x2)
		     (AND
		       (equal (nth 1 x1) (nth 1 x2))
		       (< (nth 1 (nth 2 x1)) (nth 1 (nth 2 x2)))
		     )
		   )
	 )
       )
)
В итоге обычно получается нумерация как на рисунке. Список имеет такой вид:

Код:
[Выделить все]
((<Имя объекта: 7ef89d48> "СК5-40н" (104276.0 6743.88 0.0))
(<Имя объекта: 7ef89d40> "СК5-40н" (104865.0 6743.88 0.0))
(<Имя объекта: 7ef89d38> "СК5-40н" (104276.0 7470.11 0.0))
(<Имя объекта: 7ef89d30> "СК5-40н" (104865.0 7470.11 0.0))
(<Имя объекта: 7ef897a0> "СК5-40н" (102967.0 8098.84 0.0))
(<Имя объекта: 7ef89798> СК5-40н" (103556.0 8098.84 0.0))
(<Имя объекта: 7ef89698> "СК5-40н" (104981.0 8292.79 0.0))
(<Имя объекта: 7ef89690> "СК5-40н" (105503.0 8292.79 0.0))
(<Имя объекта: 7ef89688> "СК5-40н" (106092.0 8292.79 0.0))
(<Имя объекта: 7ef89818> "СНпр3-30" (102868.0 6173.29 0.0))
(<Имя объекта: 7ef897b8> "СНпр3-30" (103541.0 6173.29 0.0))
(<Имя объекта: 7ef89800> "СНпр3-30" (104263.0 6173.29 0.0))
(<Имя объекта: 7ef89810> "СНпр3-30" (104986.0 6173.29 0.0))
(<Имя объекта: 7ef89808> "СНпр3-30" (105659.0 6173.29 0.0))
(<Имя объекта: 7ef89770> "СНпр3-30" (101705.0 6532.29 0.0))
(<Имя объекта: 7ef89760> "СНпр3-30" (102379.0 6532.29 0.0))
(<Имя объекта: 7ef896c8> "СНпр3-30" (105582.0 6754.03 0.0))
(<Имя объекта: 7ef89708> "СНпр3-30" (106304.0 6754.03 0.0))
(<Имя объекта: 7ef896f0> "СНпр3-30" (106977.0 6754.03 0.0))
(<Имя объекта: 7ef89750> "СНпр3-30" (102917.0 6864.31 0.0))
(<Имя объекта: 7ef89740> "СНпр3-30" (103591.0 6864.31 0.0))
(<Имя объекта: 7ef89768> "СНпр3-30" (101705.0 7154.83 0.0))
(<Имя объекта: 7ef89758> "СНпр3-30" (102379.0 7154.83 0.0))
(<Имя объекта: 7ef896c0> "СНпр3-30" (105582.0 7376.57 0.0))
(<Имя объекта: 7ef89700> "СНпр3-30" (106304.0 7376.57 0.0))
(<Имя объекта: 7ef896e8> "СНпр3-30" (106977.0 7376.57 0.0))
(<Имя объекта: 7ef89748> "СНпр3-30" (102917.0 7486.85 0.0))
(<Имя объекта: 7ef89738> "СНпр3-30" (103591.0 7486.85 0.0))
(<Имя объекта: 7ef89720> "СНпр3-30" (104186.0 8102.8 0.0))
(<Имя объекта: 7ef896e0> "СНпр3-30" (106977.0 8102.8 0.0)))
Тут видно, что весь список отсортирован по наименования блоков. Затем, не нарушая это сортировки, идёт сортировка по Y, и затем, при одинаковых значениях Y, сортировка идёт по X.

Всё бы хорошо, но Брикскад этого не понимает. Уже на второй сортировке он сбивает последовательность первой сортировки (наименования идут вразнобой).
Может, есть другой способ? Как я понимаю, AutoCAD каким-то образом "понимает", что я хочу сделать последовательно-приоритетную сортировку (ведь в сортировке по X я не указывал, что нужно учитывать результаты сортировки по Y, а он учёл это).
Ну а Брикскад моих намёков не понимает. Может, он поймёт по-другому?

Миниатюры
Нажмите на изображение для увеличения
Название: 1.JPG
Просмотров: 70
Размер:	12.8 Кб
ID:	32777  Нажмите на изображение для увеличения
Название: 2.JPG
Просмотров: 67
Размер:	21.2 Кб
ID:	32778  

Просмотров: 3300
 
Непрочитано 02.02.2010, 12:48
#2
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,407
Отправить сообщение для Александр Ривилис с помощью Skype™


А сделать это при помощи одной сортировки не пробовал?
Александр Ривилис вне форума  
 
Непрочитано 02.02.2010, 12:59
#3
Кулик Алексей aka kpblc
Moderator

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


Tonic, я же вроде тебе в аське отписывал код - ты его не проверял?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 02.02.2010, 13:00
#4
Tonic


 
Регистрация: 26.06.2007
Воронеж
Сообщений: 151


Александр Ривилис, То есть (vl-sort (vl-sort (vl-sort (...))))? Пробовал, результат тот же (если правильно делать и не запутаться), просто так нагляднее. Но это ведь одно и то же?

Кулик Алексей aka kpblc, пробовал - не вышло (даже в Автокаде). Вот тот код:
Код:
[Выделить все]
  (vl-sort
    (vl-sort
      (vl-sort
        test_list
        (function
          (lambda (a b)
            (<= (cadr a) (cadr b))
            ) ;_ end of lambda
          ) ;_ end of function
        ) ;_ end of vl-sort
      (function
        (lambda (a b)
          (<= (cadr (caddr a)) (cadr (caddr b)))
          ) ;_ end of lambda
        ) ;_ end of function
      ) ;_ end of vl-sort
    (function
      (lambda (a b)
        (<= (car (caddr a)) (car (caddr b)))
        ) ;_ end of lambda
      ) ;_ end of function
    ) ;_ end of vl-sort
Tonic вне форума  
 
Непрочитано 02.02.2010, 13:08
#5
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,407
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Tonic Посмотреть сообщение
Александр Ривилис, То есть (vl-sort (vl-sort (vl-sort (...))))?
Нет. Я имел ввиду один вызов (vl-sort), только функция сравнения должна быть сложнее.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 02.02.2010, 13:13
#6
Tonic


 
Регистрация: 26.06.2007
Воронеж
Сообщений: 151


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Нет. Я имел ввиду один вызов (vl-sort), только функция сравнения должна быть сложнее.
А, нет, не пробовал, т.к. до такой функции общей не додумался. Хотя, проблему восприятия Брикскадом это могло бы решить... наверно.
Tonic вне форума  
 
Непрочитано 02.02.2010, 13:19
#7
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,407
Отправить сообщение для Александр Ривилис с помощью Skype™


Честно говоря мне не очень понятно почему оно работает так как ты хотел в AutoCAD - не должно оно так работать, или должно работать не устойчиво.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 02.02.2010, 13:26
#8
Tonic


 
Регистрация: 26.06.2007
Воронеж
Сообщений: 151


Мне тоже это непонятно (ведь в третьей сортировке сохранено условие первой сортировки, но не учитываются результаты второй!). Но работает почему-то. Хотя, чтобы не было этих "почему-то", надо и правда одну общую фуекцию придумать...
Tonic вне форума  
 
Непрочитано 02.02.2010, 14:12
1 | #9
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,992
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Tonic, Если я правильно понял и правильно реализовал
Код:
[Выделить все]
(setq test_list
       '((0 "СК5-41н" (10 6 0.0))
         (0 "СК5-40н" (10 6.7 0.0))
         (0 "СК5-40н" (9 6.7 0.0))
         (0 "СК5-40н" (9 6.8 0.0))
         (0 "СК5-41н" (11 6.7 0.0))
        )
) ;_ end of setq

(setq t1
       (vl-sort test_LIST
                (function
                  (lambda (x1 x2)
                    (or
                      (< (nth 1 x1) (nth 1 x2)) ;_по именам
                      (and                      ;_В пределах одинаковых имен по Y
                        (equal (nth 1 x1) (nth 1 x2))
                        (< (nth 1 (nth 2 x1)) (nth 1 (nth 2 x2)))
                      ) ;_ end of AND
                      (and                      ;_В пределах одинаковых имен и Y по X
                        (equal (nth 1 x1) (nth 1 x2))
                        (equal (nth 1 (nth 2 x1)) (nth 1 (nth 2 x2)) 1e-6)
                        (< (nth 0 (nth 2 x1)) (nth 0 (nth 2 x2)))
                      ) ;_ end of AND

                    ) ;_ end of or
                  ) ;_ end of lambda
                ) ;_ end of function
       ) ;_ end of vl-sort
) ;_ end of setq
Должно сортировать список по именам, в перделах одинаковых имен по Y, в пределах одинаковых имен и Y по X
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 02.02.2010, 14:25
#10
Tonic


 
Регистрация: 26.06.2007
Воронеж
Сообщений: 151


VVA, отлично! Работает и там, и там. Хорошо придумано, а я уже себе мозг сломал =)
Спасибо!
P.S. Всем остальным старожилам форума также спасибо за участие и интерес!
Tonic вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Сортирвка списка последовательно, по приоритетам (вопрос)

Размещение рекламы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Справка по форуму Admin FAQ: Часто задаваемые вопросы 13 04.03.2014 11:12
Вопрос: изменение свойств участка последовательно соединённых примитивов. Tonic Программирование 19 09.10.2009 14:25
Вопрос по сортировке списка отрезков и дуг, составляющих единое целое Tonic Программирование 13 27.04.2009 01:04