longcashman 发表于 2015-1-30 11:32:33

vectra 发表于 2015-1-29 19:44 static/image/common/back.gif
无序的两个循环时间复杂度是O(n^2),排序之后,两个表均循环一次即可,时间复杂度是O(n)

我觉得跟排序没有关系
这个问题应该就是一个文字集合里面的每个文字对一个线段中点集合求distance 找出<10的来
“每个文字” “每个线段”
就是2个repeat

llsheng_73 发表于 2015-1-30 11:33:06

longcashman 发表于 2015-1-30 11:29 static/image/common/back.gif
这个法子只能判定附近有线但不一定是在中点附近的

一是选出来进一步用线的中点进行排除,二是还按原来的办法,不断变小第二层循环所涉及的表

longcashman 发表于 2015-1-30 18:52:54

llsheng_73 发表于 2015-1-30 11:33 static/image/common/back.gif
一是选出来进一步用线的中点进行排除,二是还按原来的办法,不断变小第二层循环所涉及的表

的确 计算量小了很多(defun getlinemidptlst (enlst / ent)
(mapcar '(lambda (en)
             (setq
             ent (entget en)
             )
             (mapcar
             '(lambda        (x y)
                  (* 0.5
                     (+ x y)
                  )
                )
             (cdr
               (assoc 10 ent)
             )
             (cdr
               (assoc 11 ent)
             )
             )
           )
          enlst
)
);中点表
(defun ss->lst (ss / i enlst)
(setq i 0)
(repeat (sslength ss)
    (setq enlst (cons (ssname ss i) enlst))
    (setq i (1+ i))
)
enlst
);选择集到表
(defun cc ()
(setq txtenlst (ss->lst (ssget '((0 . "TEXT")))))
(setq        textptlst (mapcar '(lambda (en) (cdr (assoc 10 (entget en))))
                          txtenlst
                  )
)
(setq        windowlst (mapcar '(lambda (pt)
                             (list (polar pt (* 2 pi) 300)
                                   (polar pt (* 0.5 pi) 300)
                             )
                           )
                          textptlst
                  )
)

(repeat (length txtenlst)
    (if        (setq
          ss (ssget "_C" (car (car windowlst)) (cadr (car windowlst)))
        )
      (progn
        (setq midptlst (getlinemidptlst (ss->lst ss)));选择到的直线取中点表
        (foreach midpt midptlst
          (if midpt
          (if        (< 300. (distance midpt (car textptlst)));直线中点与文字插入点的距离
              (vla-put-color (vlax-ename->vla-object (car txtenlst)) 1)
          )
          )
        )
      )
    )
    (setq textptlst (cdr textptlst))
    (setq txtenlst (cdr txtenlst))
    (setq windowlst (cdr windowlst))
)
)

















vectra 发表于 2015-1-30 21:38:58

本帖最后由 vectra 于 2015-1-31 20:00 编辑

代码实现及评测结果请移步

http://bbs.mjtd.com/thread-112925-1-1.html

longcashman 发表于 2015-2-1 11:03:57

vectra 发表于 2015-1-30 21:38 static/image/common/back.gif
代码实现及评测结果请移步

http://bbs.mjtd.com/thread-112925-1-1.html

分治策略的确比双repeat效率高,原理是让一个点跟某个范围而不是全部的点进行比较。但是分治有合理确定分治范围的问题,而且在实际图纸中应该是ssget得到的周边点范围更小。就是不知道综合时间哪个更快。
直觉上字少线多应该ssget更快。
有时间再验证下。
不管怎么说你都是高手!
页: 1 [2]
查看完整版本: [循环套循环]请问如何优化这个算法