Chuyển đến nội dung
Diễn đàn CADViet
Jin Yong

Hỏi về Lisp (thuật toán, ý tưởng, coding,...)

Các bài được khuyến nghị

Hoặc code này :


(defun str-split (sym str / lst i j)
 ;write by Tue_NV
 (vl-load-com)
(setq i 0 j 1)
(while (setq i (vl-string-search sym str i))
 (setq lst (append lst (list (substr str j (- i j -1)))))
 (setq  i (1+ i) j (1+ i) )
)
lst)

thử : (str-split ";" (getenv "ACAD"))

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

"[yêu cầu]Viết Lisp xắp xếp các List..."

Tôi có hai list như sau:

- list 1 chứa các giá trị: (setq ddat '(4 2 7 1 8 3 5 6 9))

- list 2 chứa các text: (setq tso '(d b g a h c e f i))

Nhờ các Bạn giúp CODE để xắp xếp hai list trên sao cho ra kết quả như sau:

...(xapxep ddat tso)...

thì trả về hai list: ( 1 2 3 4 5 6 7 8 9) và (a b c d e f g h i) tương ứng.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

"[yêu cầu]Viết Lisp xắp xếp các List..."

Tôi có hai list như sau:

- list 1 chứa các giá trị: (setq ddat '(4 2 7 1 8 3 5 6 9))

- list 2 chứa các text: (setq tso '(d b g a h c e f i))

Nhờ các Bạn giúp CODE để xắp xếp hai list trên sao cho ra kết quả như sau:

...(xapxep ddat tso)...

thì trả về hai list: ( 1 2 3 4 5 6 7 8 9) và (a b c d e f g h i) tương ứng.

Của bạn đây :

(defun sapxep(l1 l2 / lst)
 (list
(mapcar 'car (setq lst (vl-sort (mapcar '(lambda(x y) (cons x y)) ddat tso) '(Lambda (x y) (< (car x) (car y))))))
(mapcar 'cdr lst)
 )
)

 

(vl-sort ddat '(lambda (e1 e2) (< e1 e2)))

(vl-sort tso '(lambda (e1 e2) (< e1 e2)))

Hình như không đúng câu hỏi của bạn lenhatanh

Và câu này thì sai rồi bác

(vl-sort tso '(lambda (e1 e2) (< e1 e2)))

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Câu hỏi của lenhatanh tối nghĩa vậy :) Người hỏi chưa phân biệt được SYMBOL và STRING, làm câu trả lời cũng loằng ngoằng thêm :)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Của bạn đây :
 (defun sapxep(l1 l2 / lst) (list (mapcar 'car (setq lst (vl-sort (mapcar '(lambda(x y) (cons x y)) ddat tso) '(Lambda (x y) (< (car x) (car y)))))) (mapcar 'cdr lst) ) ) 

Hình như không đúng câu hỏi của bạn lenhatanh Và câu này thì sai rồi bác (vl-sort tso '(lambda (e1 e2) (< e1 e2)))

Cám ơn các Bạn !

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình có một bài toán như sau nhờ mọi người góp ý cách giải quyết:

----

Mình có 1 tập hợp các đối tượng được sắp xếp theo trường hợp ô lưới và mình muốn sử lý tùy biến nó theo 3 cách.

- Sử lý tập đối tượng đó theo phương X.

- Sử lý tập đối tượng đó theo phương Y

- Sử lý tập đối tượng đó theo thứ tự được chọn.

Ví dụ:

Mình có 1 tập hợp chuỗi. và mình muốn thay thế chuỗi này vào 1 chuổi khác cùng số lượng.

Minh họa: lấy theo phương X

1 2 3 4 5 6 7 8

A B C D E F G H

9 10 11 12 13 14 15 16

==> Kết quả: 1 2 3 4 5 6 7 8 A B C D E F G H 9 10 11 12 13 14 15 16

Minh họa: lấy theo phương Y

1 2 3 4 5 6 7 8

A B C D E F G H

9 10 11 12 13 14 15 16

==> Kết quả: 1 A 9 2 B 10 3 C 11 4 D 12 5 E 13 6 F 14 7 G 15 8 H 16

Và sử lý theo thứ tự được chọn cũng tương tự đối với 2 cách trên. Vậy mình phải sử lý như thế nào.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Đọc hoài câu hỏi của bạn, kể cả ví dụ, vẫn chưa hiểu được ý bạn.

Khái niệm "thay thế" trong ví dụ: không hiểu. Trong ví dụ có thấy cái gì thay thế cho cái gì đâu?

Khái niệm: sắp xếp theo lưới ô": cũng không hiểu luôn.

Bạn có cách chi giải thích trần truồng hơn một chút được không?

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình có một bài toán như sau nhờ mọi người góp ý cách giải quyết:

----

Mình có 1 tập hợp các đối tượng được sắp xếp theo trường hợp ô lưới và mình muốn sử lý tùy biến nó theo 3 cách.

- Sử lý tập đối tượng đó theo phương X.

- Sử lý tập đối tượng đó theo phương Y

- Sử lý tập đối tượng đó theo thứ tự được chọn.

Ví dụ:

Mình có 1 tập hợp chuỗi. và mình muốn thay thế chuỗi này vào 1 chuổi khác cùng số lượng.

 

==> Kết quả: 1 2 3 4 5 6 7 8 A B C D E F G H 9 10 11 12 13 14 15 16

 

==> Kết quả: 1 A 9 2 B 10 3 C 11 4 D 12 5 E 13 6 F 14 7 G 15 8 H 16

Và sử lý theo thứ tự được chọn cũng tương tự đối với 2 cách trên. Vậy mình phải sử lý như thế nào.

Sort theo phương X.Y thì tham khảo Lisp của Lee-Mac :

;; Renumber Text  -  Lee Mac  -  2011  -  www.lee-mac.com
;; Prompts for a selection of Text / MText objects and renumbers the
;; contents in the chosen direction, based on the text alignment point.
(defun c:rt ( / ent inc lst sel srt )
(defun LM:GroupByFunction ( lst fun / tmp1 tmp2 x1 )
   	(if (setq x1 (car lst))
       	(progn
           	(foreach x2 (cdr lst)
               	(if (fun x1 x2)
                   	(setq tmp1 (cons x2 tmp1))
                   	(setq tmp2 (cons x2 tmp2)))  )
           	(cons (cons x1 tmp1) (LM:GroupByFunction tmp2 fun)) )   )	)
(defun LM:TextInsertion ( elist )
   	(if
       	(or
           	(eq "MTEXT" (cdr (assoc 0 elist)))
           	(and
               	(zerop (cdr (assoc 72 elist)))
               	(zerop (cdr (assoc 73 elist))) ) )
       	(cdr (assoc 10 elist))
       	(cdr (assoc 11 elist)) )  )
(if (setq sel (ssget "_:L" '((0 . "MTEXT,TEXT"))))
   	(progn
       	(initget "LTR RTL TTB BTT")
       	(setq *dir*
           	(cond
               	(   (getkword
                       	(strcat "\nDirection? [LTR/RTL/TTB/BTT] <"
                           	(setq *dir* (cond ( *dir* ) ("LTR"))) ">: " ) ) )
               	(   *dir*   ) ) )
       	(repeat (setq inc (sslength sel))
           	(setq ent (entget (ssname sel (setq inc (1- inc))))
                 	lst (cons (list (LM:TextInsertion ent) ent) lst)  )  )
       	(setq inc 0)
       	(foreach row
           	(apply 'vl-sort
               	(cond
                   	(   (member *dir* '("LTR" "RTL"))
                       	(if (eq "LTR" *dir*)
                           	(setq srt (function (lambda ( a b ) (< (caar a) (caar B)))))
                           	(setq srt (function (lambda ( a b ) (> (caar a) (caar B))))) )
                       	(list
                           	(LM:GroupByFunction lst (lambda ( a b ) (equal (cadar a) (cadar B) 0.1)))
                           	(function (lambda ( a b ) (> (cadaar a) (cadaar B)))) ) )
                   	(   (member *dir* '("TTB" "BTT"))
                       	(if (eq "TTB" *dir*)
                           	(setq srt (function (lambda ( a b ) (> (cadar a) (cadar B)))))
                           	(setq srt (function (lambda ( a b ) (< (cadar a) (cadar B)))))  )
                       	(list
                           	(LM:GroupByFunction lst (lambda ( a b ) (equal (caar a) (caar B) 0.1)))
                           	(function (lambda ( a b ) (< (caaar a) (caaar B)))) ) ) )  )
           	(foreach item (vl-sort row srt)
               	(entmod
                   	(subst
                       	(cons  1 (itoa (setq inc (1+ inc))))
                       	(assoc 1 (cadr item))
                       	(cadr item) ) ) )  ) ) )
(princ))
(vl-load-com)

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Phương án: trong mỗi tập chọn (tập gốc, gọi là lst1 và tập cần thay thế, gọi là lst2), bạn sắp xếp tăng dần theo nguyên tắc:

- Nếu tọa độ X bằng nhau thì tăng dần theo Y.

- Nếu tọa độ Y bằng nhau thì tăng dần theo X.

- Khi đó bạn sẽ có 2 tập tương ứng (lst1 và lst2), quan hệ một đối một.

- Lặp n lần, mỗi lần entmod mỗi phần tử trong lis2 bởi 1 phần tử trong lst1 => sẽ có list thay thế.

Phương án này có thể áp dụng cho cả 3 kiểu thay thế của bạn. Tham khảo 1 hàm sắp xếp mà tôi đã dùng với nguyên lý gần giống bạn:

;---- Sap xep theo X tang dan, neu X bang nhau thi sap xep theo Y tang dan, by HA.

(setq lst (vl-sort lst '(lambda (e1 e2) (if (/= (car e1) (car e2)) (< (car e1) (car e2)) (< (cadr e1) (cadr e2))))))

Trong hàm trên, để chính xác, nên dùng EQUAL.

Hy vọng bạn làm được.

P/S: lisp tham khảo của bác Gia_bach không đúng ý đồ của bạn.

P/S: xem lại thì ví dụ không giống với hình minh họa của bạn?

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Đúng là ví dụ trên ko giống với hình minh họa vì mình sẽ vận dụng cú pháp của nó cho những trường hợp khác nhau chứ không hẳn là chỉ định cho 1 trường hợp cụ thể nào...

Cảm ơn đã góp ý, mình sẽ áp dụng thử. Thanks

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

1. Cho mình hỏi về cách sử dụng và chức năng của hàm "defun S::...." mình seach trên forum thì có 1 vài bài viết có sử dụng hàm này nhưng không thấy hướng dẫn cách vận dụng nó....

2. Một điều nữa là nếu như mình đặt tên 1 biến "ABC" nào đó dùng cho 2 file Lisp khác nhau và mang giá trị khác nhau thì trong quá trình làm việc có xảy ra xung đột giữa 2 giá trị được gán của biến này ko.

VD:

(setq ABC "giá trị ở Lisp 1") --> Dòng này ở lisp 1

(setq ABC "giá trị ở Lisp 2") --> Dòng này ở lisp 2

Khi lisp 1 và lisp 2 được add vào và sử dụng thì có xảy ra lỗi ko.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Trả lời câu 2 cho bạn: lỗi hay không lỗi là tùy thuộc lệnh này có hứng kết quả của lệnh kia không. Xem chuỗi ví dụ này chắc bạn hiểu.

Test theo thứ tự trên xuống.

(defun C:HA1a() ;ham thu 1 sinh ra bien a, khong khu bien a.
(setq a 0)
(princ (strcat "\n " (itoa a)))
(princ))
(defun C:HA2() ;ham thu 2 hung gia tri cua ham khac => co the bi loi
(or a (setq a 1))
(princ (strcat "\n " (itoa (/ 5 a))))
(princ))
(defun C:HA3() ;ham thu 3 set gia tri moi cho a => luon luon khong loi
(setq a 1)
(princ (strcat "\n " (itoa (/ 5 a))))
(princ))
(defun C:HA1b( / a) ;ham thu 1 sinh ra bien a, khu bien a.
(setq a 0)
(princ (strcat "\n " (itoa a)))
(princ))
(defun C:HA4() ;ham thu 4 hung gia tri cua ham khac, nhung da bi khu roi => khong loi
(or a (setq a 1))
(princ (strcat "\n " (itoa (/ 5 a))))
(princ))

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Các bạn cho mình hỏi: Có cách nào để xác định 1 block att có sử dụng field không? hoặc rộng hơn là bất kỳ đối tượng nào có sử dụng field.

Mình định ứng dụng nó để tự động lấy tập hợp các đối tượng cho lệnh UPDATEFIELD, tránh việc phải Regen bản vẽ.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Đây ban! Cái này chọn trực tiếp vào field trong block_att. Từ đó suy cho các đối tượng khác.

(setq field (cdr (assoc 3 (entget (cdr (assoc 360 (entget (CAR (NENTSEL "Chon Block_Att co chua field: ")))))))))

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Nếu bản vẽ chứa ít đối tượng thì việc regen bản vẽ không vấn đề gì. Mình không muốn regen trong trường hợp bản vẽ chứa số lượng lớn đối tượng. trong trường hợp đó, nếu ta cứ entnext thì mình chắc là không nhanh hơn việc regen là bao.

Do ý định ban đầu phá sản nên mình tính đến 1 giải pháp khác khả dĩ hơn. Chỉ UpdateField cho các đối tượng trong phạm vi nhìn thấy trên màn hình (giống hatch). cảm ơn bạn đã nhiệt tình :)

;;; reset field - Thuylinh313
(defun c:rf (/ x y c)
(setq x (getvar"screensize")
  	y (* 0.5 (getvar"viewsize"))
  	c (getvar "viewctr"))
(vl-cmdf "UPDATEFIELD"
     	(ssget "c"
    			(polar (polar c (*  0.5 pi) y) pi (/(* y (car x)) (cadr x)))
    			(polar (polar c (* -0.5 pi) y) 0  (/(* y (car x)) (cadr x)))
    			'((0 . "INSERT,*TEXT"))) "")
(princ))

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

E nghĩ có thể xài qua Reactor.

1 ví dụ :

 

(defun ST:Reactor-Clear (lstReactor)

(foreach item lstReactor (if (eval item) (progn (vlr-remove (eval item))(set item nil))))

)

 

(defun ST-Get-List-Command(objReactor lstOfCommand)

(setq #lstCmds (reverse (cons (car lstOfCommand) (reverse #lstCmds)))))

 

(ST:Reactor-Clear '(#CmdList1 #CmdList2))

(setq #CmdList1 (vlr-editor-reactor nil '((:vlr-commandended . ST-Get-List-Command))))

(setq #CmdList2 (vlr-editor-reactor nil '((:vlr-unknownCommand . ST-Get-List-Command))))

#lstCmds lưu lại list các lệnh known và unknown.Khi sử dụng lệnh AA thì lấy last list này

Ketxu có thể hướng dẫn cụ thể cách dùng mấy hàm trên để lấy lệnh cuối không? Mình cũng đang cần lấy lệnh cuối nhưng không hiểu mấy hàm trên sử dụng thế nào.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Bạn chỉ cần đặt các hàm đó cho load lên thôi.

Phần :

(defun ST:Reactor-Clear (lstReactor)

(foreach item lstReactor (if (eval item) (progn (vlr-remove (eval item))(set item nil))))

)

 

(ST:Reactor-Clear '(#CmdList1 #CmdList2))

nhằm mục đích clear reactor trước đó.

 

Biến #lstCmds đã lưu lại các lệnh đã thực hiện (kể từ khi load lisp) rồi, bạn kiểm tra giá trị biến này nhé.

Có thể đổi vlr-commandended thành :vlr-commandWillStart để bắt cả trường hợp người dùng đánh lệnh rồi esc luôn.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Đoạn code trên không ổn ketxu ạ. nó chỉ có tác dụng với các lệnh của cad. có 2 vấn đề sảy ra nó không giải quyết được:

- Các lệnh lisp (defun c:lenh....) nó hoàn toàn không nhận biết.

- Các lệnh lisp có sử dụng hàm command bên trong, nó sẽ lấy luôn command cuối cùng sử dụng trong lệnh lisp đó. mà thường thì đó là các lệnh UCS hoặc Undo.

Lệnh mà mình muốn lấy là lệnh cuối cùng giống như khi ta vừa sử dụng 1 lệnh, space hay enter tiếp thì cad gọi lại lệnh vừa sử dụng í.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay


×