`中微子 发表于 2023-8-15 01:21:27

又遇到一个表处理难题,请高手解决。顺带学习学习。

想把其中连续而且颜色一样的线组合成一条线。
(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:24:19

本帖最后由 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:53:52

本帖最后由 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-15 08:27:59

本帖最后由 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)

gaics 发表于 2023-8-15 08:14:38

(setq d 1),最后已经超出范围了

`中微子 发表于 2023-8-15 10:27:08

本帖最后由 `中微子 于 2023-8-15 10:34 编辑

vitalgg 发表于 2023-8-15 08:27

大神,这里出错了。抱歉新手不会改。
错误: no function definition: LIST:GROUP-BY

你的是一种全新的思路,但我没看懂,不好意思。

vitalgg 发表于 2023-8-15 10:41:40

看注释了解思路就行。
带冒号的都是@lisp函数库中的函数。
这个支持重叠的线。不知道你的需求中有没有重叠的情况。

@lisp函数库全面开源
https://gitee.com/atlisp/atlisp-lib

https://gitee.com/atlisp/atlisp-lib/blob/main/src/list/group-by.lsp

`中微子 发表于 2023-8-15 11:18:15

vitalgg 发表于 2023-8-15 10:41
看注释了解思路就行。
带冒号的都是@lisp函数库中的函数。
这个支持重叠的线。不知道你的需求中有没有重 ...

非常感谢!学习了。运行成功。谢谢!!

gaics 发表于 2023-8-15 12:21:41

本帖最后由 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)
)

`中微子 发表于 2023-8-15 16:11:14

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)

`中微子 发表于 2023-8-15 16:16:17

gaics 发表于 2023-8-15 13:24
保留完全相同的元素

请看9楼,也有同样的容差问题。求解决。辛苦了!!
页: [1] 2
查看完整版本: 又遇到一个表处理难题,请高手解决。顺带学习学习。