又遇到一个表处理难题,请高手解决。顺带学习学习。
想把其中连续而且颜色一样的线组合成一条线。(setq waco1 '((0 1 1) (1 1 1) (3 2 2) (5 3 3) (9 1 4) (10 2 4) (12 1 5)))
如图:说明(12 1 5) 12是开始距离,1是线长,5是颜色
输出应该是((0 2 1) (3 2 2) (5 3 3) (9 3 4) (12 1 5))
下面的我写的,几乎成功,但最后一组没法加进去。(如果最后一组线和前面线是连续的颜色也一样就不需要)
(defun c:tt ( / d e waco waco1)
(setq waco1 '((0 1 1) (1 1 1) (3 2 2) (5 3 3) (9 1 4) (10 2 4) (12 1 5)))
(setq d 1)
(setq e (nth (- d 1) waco1))
(while (<= d (- (length waco1) 1))
(if (and (= (+ (car e) (cadr e)) (car (nth d waco1))) (= (caddr e) (caddr (nth d waco1))))
(progn
(setq e (list (car e) (+ (cadr e) (cadr (nth d waco1))) (caddr e)))
(setq waco (cons e waco))
)
(progn
(setq waco (cons e waco))
(setq e (nth d waco1))
)
)
(setq d (+ d 1))
)
(setq waco (vl-sort waco '(lambda (s1 s2)(< (car s1) (car s2)))))
(print waco)
(princ)
)
先谢谢各位大神!代码写得又长又烂,请多多指教。 本帖最后由 gaics 于 2023-8-15 13:48 编辑
保留完全相同的元素
(defun c:t8 (/ d e e2 waco i)
(setq waco '((0 1 1)(1 1 1)(3 2 2)(5 3 3)(9 1 4)(10 2 4)(12 1 5)))
(setq waco (vl-sort waco '(lambda (s1 s2) (< (car s1) (car s2)))))
(setq d 0)
(while (< d (length waco))
(setq e (nth d waco))
(setq i 0)
(while (< i (length waco))
(if (and (= (+ (car e) (cadr e)) (car (nth (+ d i 1) waco)))
(= (caddr e) (caddr (nth (+ d i 1) waco)))
)
(progn
(setq e2 (list (car e)(+ (cadr e)(cadr (nth (+ d i 1) waco)))(caddr e)))
;;(setq waco (subst e2 e (vl-remove (nth (+ d i 1) waco) waco)))
(setq waco (subst e2 e (BF-List-RemoveIndex waco (+ d i 1))))
(setq e e2)
)
(setq i (1+ i))
)
)
(setq d (1+ d))
)
(print waco)
(setq waco (vl-sort waco '(lambda (s1 s2) (< (car s1) (car s2)))))
(princ)
)
(defun BF-List-RemoveIndex (lst index / i)
(setq i -1)
(vl-remove-if '(lambda (x) (= (setq i (1+ i)) index)) lst)
)
本帖最后由 vitalgg 于 2023-8-16 06:57 编辑
(setq waco1
'((0 468.548 1) (468.548 1332.85 1) (3041.5 675.413 4) (5396.91 547.939 3) (5944.85 360.787 3) (7145.64 278.132 3) (7423.77 991.957 3) (8415.73 468.926 4)))
(princ "原表:")(princ waco1)
;; 按色号排序并分组
(setq waco1 (vl-sort
waco1
'(lambda (x y)
(<
(last x)
(last y)))))
(setq waco1 (list:group-by
waco1
'(lambda (x y)
(=
(last x)
(last y)))))
;; 组内起点从小到大排序
(setq waco1 (mapcar
'(lambda (x)
(vl-sort
x
'(lambda (m n)
(< (car m) (car n)))))
waco1))
;; (princ "\n排序表:")(princ waco1)
;; 合并同色且连续的,即前一个的起点+长度 >= 紧临表的起点
(defun join-line (lst / res fuzz)
(setq fuzz 0.01)
(setq res (cons (car lst) nil))
(while (setq lst (cdr lst))
(if
(and
(setq f (car res))
(>= (+ (+ (car f) (cadr f)) fuzz) (caar lst)))
(setq res (cons
(list
(caar res)
(max
(+ (cadar lst) (- (caar lst) (caar res)))
(cadar res))
(last (car res)))
(cdr res)))
(setq res (cons (car lst) res))))
(reverse res)
)
(princ "\n结果:")(princ (apply 'append (mapcar 'join-line waco1)))
(princ)
非得有现成的函数才会用容差吗?
(>= (+ (+ (car f) (cadr f)) fuzz) (caar lst)))
本帖最后由 vitalgg 于 2023-8-16 06:53 编辑
(setq waco1 '((0 1 1) (1 1 1) (3 2 2) (5 3 3) (9 1 4) (10 2 4) (12 1 5)))
(princ "原表:")(princ waco1)
;; 按色号排序并分组
(setq waco1 (vl-sort
waco1
'(lambda (x y)
(<
(last x)
(last y)))))
(setq waco1 (list:group-by
waco1
'(lambda (x y)
(=
(last x)
(last y)))))
;; 组内起点从小到大排序
(setq waco1 (mapcar
'(lambda (x)
(vl-sort
x
'(lambda (m n)
(< (car m) (car n)))))
waco1))
;; 合并同色且连续的,即前一个的起点+长度 >= 紧临表的起点
(defun join-line (lst / res)
(setq res (cons (car lst) nil))
(while (setq lst (cdr lst))
(if
(and
(setq f (car res))
(>= (+ (car f) (cadr f)) (caar lst)))
(setq res (cons
(list
(caar res)
(max
(+ (cadar lst) (- (caar lst) (caar res)))
(cadar res))
(last (car res)))
(cdr res)))
(setq res (cons (car lst) res))))
(reverse res)
)
(princ "\n结果:")(princ (apply 'append (mapcar 'join-line waco1)))
(princ)
(setq d 1),最后已经超出范围了 本帖最后由 `中微子 于 2023-8-15 10:34 编辑
vitalgg 发表于 2023-8-15 08:27
大神,这里出错了。抱歉新手不会改。
错误: no function definition: LIST:GROUP-BY
你的是一种全新的思路,但我没看懂,不好意思。
看注释了解思路就行。
带冒号的都是@lisp函数库中的函数。
这个支持重叠的线。不知道你的需求中有没有重叠的情况。
@lisp函数库全面开源
https://gitee.com/atlisp/atlisp-lib
https://gitee.com/atlisp/atlisp-lib/blob/main/src/list/group-by.lsp
vitalgg 发表于 2023-8-15 10:41
看注释了解思路就行。
带冒号的都是@lisp函数库中的函数。
这个支持重叠的线。不知道你的需求中有没有重 ...
非常感谢!学习了。运行成功。谢谢!! 本帖最后由 gaics 于 2023-8-15 13:49 编辑
我也来试一下
(defun c:t7 (/ d e e2 waco i)
(setq waco '((0 1 1)(1 1 1)(3 2 2)(5 3 3)(9 1 4)(10 2 4)(12 1 5)))
(setq waco (vl-sort waco '(lambda (s1 s2) (< (car s1) (car s2)))))
(setq d 0)
(while (< d (length waco))
(setq e (nth d waco))
(setq i 0)
(while (< i (length waco))
(if (and (= (+ (car e) (cadr e)) (car (nth (+ d i 1) waco)))
(= (caddr e) (caddr (nth (+ d i 1) waco)))
)
(progn
(setq e2 (list (car e)(+ (cadr e)(cadr (nth (+ d i 1) waco)))(caddr e)))
(setq waco (subst e2 e (vl-remove (nth (+ d i 1) waco) waco)))
(setq e e2)
)
(setq i (1+ i))
)
)
(setq d (1+ d))
)
(print waco)
(setq waco (vl-sort waco '(lambda (s1 s2) (< (car s1) (car s2)))))
(princ)
)
vitalgg 发表于 2023-8-15 10:41
看注释了解思路就行。
带冒号的都是@lisp函数库中的函数。
这个支持重叠的线。不知道你的需求中有没有重 ...
刚试了,希望能加入一点容差进去。把表换成((0 468.548 1) (468.548 1332.85 1) (3041.5 675.413 4) (5396.91 547.939 3) (5944.85 360.787 3) (7145.64 278.132 3) (7423.77 991.957 3) (8415.73 468.926 4))
输出应该是:((0 1801.4 1) (3041.5 675.413 4) (5396.91 908.726 3) (7145.64 1270.09 3))(8415.73 468.926 4)
我把IF条件改成(>= (atof(rtos(+ (car f) (cadr f))2 2)) (atof(rtos(caar lst)2 2)))只保留后二位还是不行
输出是((0 1801.4 1) (3041.5 675.413 4) (5396.91 908.727 3) (7423.77 991.957 3) (8415.73 468.926 4))。
这一项是差的(7423.77 991.957 3) gaics 发表于 2023-8-15 13:24
保留完全相同的元素
请看9楼,也有同样的容差问题。求解决。辛苦了!!
页:
[1]
2