Đến nội dung


Hình ảnh
- - - - -

Thuật toán xắp xếp đối tượng trong tập hợp


  • Please log in to reply
12 replies to this topic

#1 nataca

nataca

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 712 Bài viết
Điểm đánh giá: 553 (tốt)

Đã gửi 14 August 2008 - 10:33 AM

Mình đang viết Lisp sắp xếp tập hợp các dòng text theo thứ tự tăng dần theo tọa độ Y của dòng Text (Dòng text này nằm ngang). Vì khi mình chọn tập hợp bằng chuột thì nó sẽ xắp xếp tập hợp theo thứ tự chọn trước chọn sau. Mình đau đầu mà vẫn chưa tìm ra được thuật toán giải quyết được vấn đề này. Mọi người giúp mình đoạn code giải quyết vấn đề trên được không
  • 0

#2 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 14 August 2008 - 11:37 AM

Mình đang viết Lisp sắp xếp tập hợp các dòng text theo thứ tự tăng dần theo tọa độ Y của dòng Text (Dòng text này nằm ngang). Vì khi mình chọn tập hợp bằng chuột thì nó sẽ xắp xếp tập hợp theo thứ tự chọn trước chọn sau. Mình đau đầu mà vẫn chưa tìm ra được thuật toán giải quyết được vấn đề này. Mọi người giúp mình đoạn code giải quyết vấn đề trên được không

Ví dụ đây bạn:

(defun c:test ()
(setq ss (ssget '((0 . "TEXT")))
lst (ss2ent ss)
lst (vl-sort lst
'(lambda (e1 e2)
(<
(caddr (assoc 10 (entget e1)))
(caddr (assoc 10 (entget e2)))
)
)
)
)
(foreach e lst
(command ".erase" e "")
(getstring "\nNhan enter de tiep tuc!")
)
)

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

  • 1

#3 nataca

nataca

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 712 Bài viết
Điểm đánh giá: 553 (tốt)

Đã gửi 14 August 2008 - 02:25 PM

Ví dụ đây bạn:

Cám ơn bác NguyenHoanh. Phải công nhận hàm vl-sort hay thật. Tiện đây bác cho em hỏi luôn: Nhóm hàm vl-* có gì đặc biệt hơn các hàm thông dụng khác vì em thấy trong sách thường không đề cập đến nó mà bác thì lại rất hay dùng nhóm hàm này? Một lần nữa rất cám ơn bác. :s_big:
  • 0

#4 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 14 August 2008 - 04:24 PM

... Nhóm hàm vl-* có gì đặc biệt hơn các hàm thông dụng khác vì em thấy trong sách thường không đề cập đến nó ...

Vl-* là các hàm mở rộng từ khi AutoDesk phát triển Visual Lisp. Chúng không có gì đặc biệt hơn các hàm khác. Tác dụng: có nhiều "đồ chơi" hơn -> bạn có nhiều lựa chọn hơn khi lập trình, code gọn gàng hơn, làm việc đỡ vất vả hơn...
Các sách ít đề cập nhưng trong Help thì có đủ. Bạn vào Developer Help>AutoLisp Reference>V Functions sẽ thấy cả đám vl-*.
Liếc qua cú pháp của chúng, xem và làm theo các ví dụ là hiểu liền. Nhiều cái hay phết, không riêng gì vl-sort...
  • 1

#5 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 01 February 2010 - 04:36 AM

Chào cả nhà.
Nhân có topic của Nataca nói về thuật toán sắp xếp thứ tự đối tượng, các bác cho Tue_NV hỏi chút :

Việc sử dụng hàm vl-sort đôi lúc lại không như ý muốn của người lập trình
- Hàm vl-sort nó sắp xếp các kí tự chuỗi theo alphabet.
Ví dụ như List :
(setq L (list "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "98" "99" "100"))
(vl-sort L '<)
khi sử dụng vl-sort nó sắp xếp các kí tự chuỗi theo alphabet.
=> Kết quả sẽ trả về như thế này thì không theo ý của User
("1" "10" "100" "11" "12" "2" "3" "4" "5" "6" "7" "8" "9" "98" "99")
-> Nó ưu tiên sắp xếp kí tự "1.." trước
Ý của User là khi sắp xếp xong thì nó sẽ thành như vậy
("1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "98" "99" "100")

Nhưng khi ta set nó về số thì sẽ đúng theo ý User
.Ví dụ :
(setq L (list 1 2 3 4 5 6 7 8 9 10 11 12 99 100))
(vl-sort L '<)
(1 2 3 4 5 6 7 8 9 10 11 12 99 100)

Nhưng không phải lúc nào ta cũng set về trường hợp số cụ thể ở trên được.
Các bác cho Tue_NV hỏi chổ này nhé.
Ví dụ sắp xếp List này :
(setq L (list "D1A" "D3" "D7" "D4" "D9" "D10B" "D10A" "D11" "D2" "D20A"))
(vl-sort L '<)
-> Kết quả trả về :
("D10A" "D10B" "D11" "D1A" "D2" "D20A" "D3" "D4" "D7" "D9")
Ý của mình là :
("D1A" "D2" "D3" "D4" "D7" "D9" "D10A" "D10B" "D11" "D20A")

Thật sự Tue_NV rất đau đầu về vấn đề này mà chưa có hướng khắc phuc
Rất mong được sự giúp đỡ của các bác
Tue_NV xin cảm ơn rất nhiều
  • 0

#6 trinhvqh

trinhvqh

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 408 Bài viết
Điểm đánh giá: 222 (khá)

Đã gửi 01 February 2010 - 07:52 AM

Thật sự Tue_NV rất đau đầu về vấn đề này mà chưa có hướng khắc phuc
Rất mong được sự giúp đỡ của các bác
Tue_NV xin cảm ơn rất nhiều


Mong các cao thủ lisp hãy giúp đỡ Tue_NV những thắc mắc về Lisp
Còn tôi, xin chữa bệnh đau đầu của Tue_NV với 500mg Paracetamol
(Nhớ ăn sáng rồi uống thuốc)
:undecided:
  • 0

#7 nataca

nataca

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 712 Bài viết
Điểm đánh giá: 553 (tốt)

Đã gửi 01 February 2010 - 08:14 AM

("D10A" "D10B" "D11" "D1A" "D2" "D20A" "D3" "D4" "D7" "D9")
Ý của mình là :
("D1A" "D2" "D3" "D4" "D7" "D9" "D10A" "D10B" "D11" "D20A")

Thật sự Tue_NV rất đau đầu về vấn đề này mà chưa có hướng khắc phuc
Rất mong được sự giúp đỡ của các bác
Tue_NV xin cảm ơn rất nhiều

Đúng là với chuổi thì cách sắp xếp của nó theo thứ tự từng ký tự từ trái qua phải. Cái này cũng gặp cả ở trong sắp xếp trong Excel. Để thuật toán sắp xếp đúng theo Number thì không còn cách nào khác bác phải biến nó thành Number hoặc tạo một chỉ số Number cho nó.
Trong trường hợp này theo ý em là mình sẽ lọc các số từ chuỗi.
Ví dụ:
"D1A" -> 1
"D2" -> 2
....
sau đó cho các số này đi kèm cùng chuỗi coi như nó là chỉ số thứ tự của chuỗi.
=> ( ("D1A" 1) (D2 2).....("D10A" 10) ... )
Như vậy trong thuật toán sắp xếp đối tượng ta sẽ sắp xếp list trên theo phần tử thứ 2 của mỗi list con (có thể là phần từ đầu hoặc vị trí nào đó tuỳ ý người lập trình )
  • 0

#8 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 01 February 2010 - 09:14 AM

Đúng là với chuổi thì cách sắp xếp của nó theo thứ tự từng ký tự từ trái qua phải. Cái này cũng gặp cả ở trong sắp xếp trong Excel. Để thuật toán sắp xếp đúng theo Number thì không còn cách nào khác bác phải biến nó thành Number hoặc tạo một chỉ số Number cho nó.
Trong trường hợp này theo ý em là mình sẽ lọc các số từ chuỗi.
Ví dụ:
"D1A" -> 1
"D2" -> 2
....
sau đó cho các số này đi kèm cùng chuỗi coi như nó là chỉ số thứ tự của chuỗi.
=> ( ("D1A" 1) (D2 2).....("D10A" 10) ... )
Như vậy trong thuật toán sắp xếp đối tượng ta sẽ sắp xếp list trên theo phần tử thứ 2 của mỗi list con (có thể là phần từ đầu hoặc vị trí nào đó tuỳ ý người lập trình )

Không đơn giản như Nataca nghĩ như "D1A"; "D1B"
Hay các trường hợp khác như :
D1; D1-1; D2; D3; D10; D10-1; D10-2
thì sẽ phải lọc như thế nào.
Tue_NV đã từng giải quyết vấn đề trên theo cách của Nataca ở đây :
Bai viet so 19 - Nhờ Viết Lisp thống kê bản vẽ
Nhưng đây là trường hợp cụ thể chưa phải là trường hợp tổng quát

Khi giải quyết 1 vấn đề thì Mình nên đặt nó vào trường hợp tổng quát Nataca à.
Thanks
  • 0

#9 nataca

nataca

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 712 Bài viết
Điểm đánh giá: 553 (tốt)

Đã gửi 01 February 2010 - 09:51 AM

Không đơn giản như Nataca nghĩ như "D1A"; "D1B"
Hay các trường hợp khác như :
D1; D1-1; D2; D3; D10; D10-1; D10-2
thì sẽ phải lọc như thế nào.
Tue_NV đã từng giải quyết vấn đề trên theo cách của Nataca ở đây :
Bai viet so 19 - Nhờ Viết Lisp thống kê bản vẽ
Nhưng đây là trường hợp cụ thể chưa phải là trường hợp tổng quát

Khi giải quyết 1 vấn đề thì Mình nên đặt nó vào trường hợp tổng quát Nataca à.
Thanks

Thì mình sẽ lập 1 công thức tổng quát cho thứ tự ưu tiên thôi anh ạ. Em ví dụ:

Cho chạy từ ký tự đầu tiên đến cuối cùng của chuỗi
Nếu ký tự trước và sau đều là số thì ghép vào nhau
Nếu ký tự sau khác số thì hoàn tất số ưu tiên thứ nhất -> (setq LstN (append LstN số))

Cứ như thế ta được list số thứ tự theo cấp ưu tiên sắp xếp ( STT ưu tiên 1, STT tư tiên 2.....STT ưu tiên n)
Dùng hàm vl-sort để sắp xếp theo thứ tự cùng cấp ưu tiên. Nếu cấp 1 bằng nhau thì xét đến cấp 2, cấp 3

=> Kết luận: Ngoài việc Sắp xếp sao cho nó đúng ý thì người lập danh sách phải hình thành ngay trong đầu quy tắc ưu tiên của từng phần tử trong danh sách. Nếu cấp độ ưu tiên mà lung tung thì bó tay.
  • 0

#10 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 01 February 2010 - 11:45 AM

Thì mình sẽ lập 1 công thức tổng quát cho thứ tự ưu tiên thôi anh ạ. Em ví dụ:

Cho chạy từ ký tự đầu tiên đến cuối cùng của chuỗi
Nếu ký tự trước và sau đều là số thì ghép vào nhau
Nếu ký tự sau khác số thì hoàn tất số ưu tiên thứ nhất -> (setq LstN (append LstN số))

Cứ như thế ta được list số thứ tự theo cấp ưu tiên sắp xếp ( STT ưu tiên 1, STT tư tiên 2.....STT ưu tiên n)
Dùng hàm vl-sort để sắp xếp theo thứ tự cùng cấp ưu tiên. Nếu cấp 1 bằng nhau thì xét đến cấp 2, cấp 3

=> Kết luận: Ngoài việc Sắp xếp sao cho nó đúng ý thì người lập danh sách phải hình thành ngay trong đầu quy tắc ưu tiên của từng phần tử trong danh sách. Nếu cấp độ ưu tiên mà lung tung thì bó tay.

Trường hợp của Tue_NV không tổng quát nên không sử dụng được hàm mặc định.

Tue_NV có thể dùng cấu trúc:
(defun sosanh(A B )
;;; nếu A đứng trước B trong list thì trả về t, ngược lại thì trả về nil
)
(vl-sort L 'sosanh)
  • 0

#11 trinhvqh

trinhvqh

    biết lệnh block

  • Members
  • PipPipPipPipPipPip
  • 408 Bài viết
Điểm đánh giá: 222 (khá)

Đã gửi 01 February 2010 - 01:13 PM

Như vậy, không có giải pháp nào cho Tue_NV sao?
Tue_NV muốn đưa ra một giải pháp tổng quát dựa trên một trường hợp không tổng quát.

Như vậy, theo ý mình (và ý của nataca) giải pháp để sắp xếp thứ tự Ký hiệu bản vẽ thì trước hết
Tue_NV nên chủ động đặt ra luật chơi. Từ đó người dùng phải tuân theo để có thể điều khiển duoc

Không nên ra sức đau đầu từ một Attribute (text) của người dùng được
Theo ý mình: Ở đây có thể phân ra 03 cấp độ:

01. Bộ môn ưu tiên: (CN; CĐ; KT; KC,..) Sắp xếp theo thứ tự a,b,c
02. Số bản vẽ: 01, 02,..,10,11,..., (Sắp xếp theo thứ tự từ nhỏ đến lớn)
03. Ký hiệu phát sinh trong quá trình Modify (01a; 01b; 01-1; 01;02,..) Sắp xếp theo thứ tự a,b,c hoặc theo thứ tự số
  • 0

#12 Demigod

Demigod

    biết pan

  • Members
  • Pip
  • 5 Bài viết
Điểm đánh giá: 3 (bình thường)

Đã gửi 20 April 2013 - 06:40 AM

Chào cả nhà.
Nhân có topic của Nataca nói về thuật toán sắp xếp thứ tự đối tượng, các bác cho Tue_NV hỏi chút :

Việc sử dụng hàm vl-sort đôi lúc lại không như ý muốn của người lập trình
- Hàm vl-sort nó sắp xếp các kí tự chuỗi theo alphabet.
Ví dụ như List :
(setq L (list "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "98" "99" "100"))
(vl-sort L '<)
khi sử dụng vl-sort nó sắp xếp các kí tự chuỗi theo alphabet.
=> Kết quả sẽ trả về như thế này thì không theo ý của User
("1" "10" "100" "11" "12" "2" "3" "4" "5" "6" "7" "8" "9" "98" "99")
-> Nó ưu tiên sắp xếp kí tự "1.." trước
Ý của User là khi sắp xếp xong thì nó sẽ thành như vậy
("1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "98" "99" "100")

Nhưng khi ta set nó về số thì sẽ đúng theo ý User
.Ví dụ :
(setq L (list 1 2 3 4 5 6 7 8 9 10 11 12 99 100))
(vl-sort L '<)
(1 2 3 4 5 6 7 8 9 10 11 12 99 100)

Nhưng không phải lúc nào ta cũng set về trường hợp số cụ thể ở trên được.
Các bác cho Tue_NV hỏi chổ này nhé.
Ví dụ sắp xếp List này :
(setq L (list "D1A" "D3" "D7" "D4" "D9" "D10B" "D10A" "D11" "D2" "D20A"))
(vl-sort L '<)
-> Kết quả trả về :
("D10A" "D10B" "D11" "D1A" "D2" "D20A" "D3" "D4" "D7" "D9")
Ý của mình là :
("D1A" "D2" "D3" "D4" "D7" "D9" "D10A" "D10B" "D11" "D20A")

Thật sự Tue_NV rất đau đầu về vấn đề này mà chưa có hướng khắc phuc
Rất mong được sự giúp đỡ của các bác
Tue_NV xin cảm ơn rất nhiều

 
 
Không biết giải pháp ở đây có giải quyết được cho Tue_NV không? tham khảo link này nhé, hy vọng giúp ích
Sắp xếp danh sách chuỗi
 


  • 0

#13 Superlong

Superlong

    biết vẽ arc

  • Members
  • PipPip
  • 49 Bài viết
Điểm đánh giá: -9 (bình thường)

Đã gửi 20 March 2016 - 05:56 PM

   BÁC HOANH cho em hỏi sao em dùng lisp trên đổi lại đối tượng là LWPOLYLINE thì lại lỗi
em đang muốn tạo một lisp tính diện tích từ tọa độ của các polyline được chọn theo cách là lấy tọa độ của đường pline có tung độ Y lớn nhất hợp với tọa độ của từng pline -> diện tích của từng vùng nên cần tìm hiểu từng bước mong được bác hoanh và mọi người hướng dẫn


  • 0