明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: x_s_s_1

[悬10币求]如何求出多个带分隔符字符串每段的最大值并返回带分隔符最大字符串(具体详

  [复制链接]
发表于 2011-10-30 10:32:04 | 显示全部楼层
我不去编程,只是给你个思路。
1、用(ssget "X" (list '(0 . "TEXT")(cons 1 特征字符)))选择
2、针对不同位置进行分组,通过(nth 2 (assoc 10 (entget 图元)))比较Y坐标值决定归属
3、用分割字符串函数提取特征数字,这个函数可以在帖子http://bbs.mjtd.com/forum.php?mo ... mp;page=1#pid486747中找到inpos
4、(eval (cons 'max (mapcar 'atof 'inpos返回的表)))求最大值
5、rtof转成字符串
6、strcat连接"G" "-" "VT"等字符
7、用(entmake (list '(0 . "TEXT")(cons 1 第6步的文本)(cons 10 插入点)))

评分

参与人数 1明经币 +1 金钱 +10 收起 理由
x_s_s_1 + 1 + 10 谢谢

查看全部评分

 楼主| 发表于 2011-10-30 11:36:21 | 显示全部楼层
cabinsummer 发表于 2011-10-30 10:32
我不去编程,只是给你个思路。
1、用(ssget "X" (list '(0 . "TEXT")(cons 1 特征字符)))选择
2、针对不同 ...

非常感谢,看看下面的代码最后一段看怎么改改
  1. ;; ! ***************************************************************************
  2. ;; ! TBC:Sort
  3. ;; ! ***************************************************************************
  4. ;; ! 功  能  : 按数字大小排序.
  5. ;; ! 参  数  : lst需排序的表,func排序方式。“'<”为升序,“'>”为降序。
  6. ;; ! 返回值  : 'Lst' - is a list of LL and UR
  7. ;; ! 说  明  : 适用 AutoCAD 2000+
  8. ;; ! from    : tengte
  9. ;; ! Web     : http://bbs.mjtd.com/thread-79299-1-1.html
  10. ;; ! ****************************************************************************
  11. (defun TBC:Sort        (lst func / Split CompFunc tmp)
  12.   (defun Split (str / tmp i n p x len lst1 lst)
  13.     (setq tmp  (vl-string->list str)
  14.           lst1 (mapcar '(lambda (x) (and (<= 48 x) (<= x 57))) tmp)
  15.           n    (length lst1)
  16.           i    0
  17.     ) ;_ 结束setq
  18.     (while (< i n)
  19.       (setq x (nth i lst1)
  20.             i (1+ i)
  21.       ) ;_ 结束setq
  22.       (if (= i 1)
  23.         (setq p        1
  24.               len 1
  25.         )                                ;else
  26.         (if (= x (nth (- i 2) lst1))
  27.           (setq len (1+ len))                ;else
  28.           (setq        tmp (substr str p len)
  29.                 tmp (if        x
  30.                       tmp
  31.                       (atoi tmp)
  32.                     ) ;_ 结束if
  33.                 lst (append lst (list tmp))
  34.                 p   i
  35.                 len 1
  36.           ) ;_ 结束setq
  37.         )                                ;if
  38.       )                                        ;if
  39.     )                                        ;while
  40.     (if        (> n 0)
  41.       (setq tmp        (substr str p len)
  42.             tmp        (if x
  43.                   (atoi tmp)
  44.                   tmp
  45.                 ) ;_ 结束if
  46.             lst        (append lst (list tmp))
  47.       ) ;_ 结束setq
  48.     ) ;_ 结束if
  49.     lst
  50.   ) ;_ 结束defun
  51.   (defun CompFunc (lst1 lst2 / tmp do flag i n el1 el2 typ1 typ2)
  52.     (setq i  0
  53.           n  (min (length lst1) (length lst2))
  54.           do T
  55.     ) ;_ 结束setq
  56.     (while (and do (<= i n))
  57.       (setq el1         (nth i lst1)
  58.             typ1 (type el1)
  59.             el2         (nth i lst2)
  60.             typ2 (type el2)
  61.             i         (1+ i)
  62.       ) ;_ 结束setq
  63.       (if (= typ1 typ2)
  64.         (setq do   (= el1 el2)
  65.               flag (eval (list func el1 el2))
  66.         )                                ;else
  67.         (setq do   nil
  68.               flag (or (= typ1 'nil) (= typ2 'STR))
  69.         ) ;_ 结束setq
  70.       )                                        ;if
  71.     )                                        ;while
  72.     flag
  73.   ) ;_ 结束defun
  74.   (setq        tmp (mapcar 'Split lst)
  75.         tmp (vl-sort-i tmp 'CompFunc)
  76.         tmp (mapcar '(lambda (x) (nth x lst)) tmp)
  77.   ) ;_ 结束setq
  78.   tmp
  79. ) ;_ 结束defun
  80. (setq bb '(("G0.1" "G0.2" "G0.3") ("G0.4" "G0.5" "G0.6") ("G10" "G8" "G6")("G5" "G3" "G1")))
  81. (vl-string-right-trim
  82.   "-"
  83.   (apply 'strcat
  84.          (mapcar '(lambda (x) (strcat x "-"))
  85.                  (mapcar '(lambda (x)
  86.                             (car x)
  87.                           ) ;_ 结束lambda
  88.                          (mapcar '(lambda (x) (TBC:Sort x '>))
  89.                                  (apply 'mapcar (cons 'list bb))
  90.                                         ;得到转置矩阵
  91.                          ) ;_ 结束mapcar;对转置矩阵进行排序
  92.                  ) ;_ 结束mapcar;提取排序后最大值表
  93.          ) ;_ 结束mapcar
  94.   ) ;_ 结束apply;连接字符串
  95. ) ;_ 结束vl-string-right-trim;删除最后的"-"


点评

排序浪费时间,直接用max求表中最大值,参见vlisp帮助  发表于 2011-10-30 13:59
发表于 2011-10-30 13:58:56 | 显示全部楼层
x_s_s_1 发表于 2011-10-30 11:36
非常感谢,看看下面的代码最后一段看怎么改改

为什么要排序?你的目标不是求最大值吗?
比如:(setq bb '(("G0.1" "G0.2" "G0.3") ("G0.4" "G0.5" "G0.6") ("G10" "G8" "G6")("G5" "G3" "G1")))
那么表中每个子表的最大值就是
(setq bb1 (nth 0 bb) bb2 (nth 1 bb) bb3 (nth 2 bb) bb4 (nth 3 bb))
(setq max1 (strcat "G" (rtos (eval (cons 'max (mapcar 'atof (mapcar '(lambda(x)(vl-string-left-trim "G" x)) bb1)))) 2 2)))
(setq max2 (strcat "G" (rtos (eval (cons 'max (mapcar 'atof (mapcar '(lambda(x)(vl-string-left-trim "G" x)) bb2)))) 2 2)))
(setq max3 (strcat "G" (rtos (eval (cons 'max (mapcar 'atof (mapcar '(lambda(x)(vl-string-left-trim "G" x)) bb3)))) 2 2)))
(setq max4 (strcat "G" (rtos (eval (cons 'max (mapcar 'atof (mapcar '(lambda(x)(vl-string-left-trim "G" x)) bb4)))) 2 2)))
这四个max值已经可以用作entmake了
 楼主| 发表于 2011-10-30 15:30:59 | 显示全部楼层
本帖最后由 x_s_s_1 于 2011-10-30 15:38 编辑
cabinsummer 发表于 2011-10-30 13:58
为什么要排序?你的目标不是求最大值吗?
比如:(setq bb '(("G0.1" "G0.2" "G0.3") ("G0.4" "G0.5" "G0 ...


谢谢,但是您误解我的意图了,以例图的G打头文字为例,G1.2-0.2,G0.2-0.2,G0.2-0.5我要得到的为G1.2-0.5,1.2为G后的最大值,0.5为-后的最大值,我的做法是先得到一个矩阵((G1.2 0.2)(G0.2 0.2)(G0.2 0.5))然后求出其转置矩阵((G1.2 G0.2 G0.2) (0.2 0.2 0.5)),再将转置矩阵排序为((G1.2 G0.2 G0.2) (0.5 0.2 0.2)),最后的出想要的结果(G1.2 0.5)再将其连接成G1.2-0.5(所有双引号省略),还有使用rtos有个问题就是我的数据存在不确定性,假设G后为2,最后得出可能为G2.0。例图只有三组数据,实际可能有几十组数据。
发表于 2011-10-30 16:19:38 | 显示全部楼层
本帖最后由 cabinsummer 于 2011-10-30 16:54 编辑
x_s_s_1 发表于 2011-10-30 15:30
谢谢,但是您误解我的意图了,以例图的G打头文字为例,G1.2-0.2,G0.2-0.2,G0.2-0.5我要得到的为G1.2-0. ...


(setvar "dimzin" 8)可以抑制rtos后面的0
你的做法复杂了,用inpos将每个G开头的字符串按-分割成两段,inpos返回的是表("G1.2" "0.2")("G0.2" "0.2")("G0.2" "0.5")将每个表对应的项组成新表("G1.2" "G0.2" "G0.2")("0.2" "0.2" "0.5")
直接用我上面给出的函数求最大值返回两个值max1="G1.2"和max2="0.5",再用(strcat max1 "-" max2)
多少组都可以做,因为(max para1 para2 para3 ......)多少项都可以求最大值,如果你不需要有结果"G0.2-0.2"那就不需要排序。

分割字符串函数
  1. (defun inpos(sep str / pos prestr sufstr russtr)
  2.   (if (setq pos (vl-string-search sep str))
  3.     (progn
  4.       (setq prestr (substr str 1 pos))
  5.       (setq sufstr (substr str (+ pos 1 (strlen sep))))
  6.       (setq russtr (list prestr sufstr))
  7.     )
  8.   )
  9. )


例如
(inpos "-" "G0.2-0.2") 返回 ("G0.2" "0.2")
(inpos "VT" "VT1-0.2") 返回 ("" "1-0.2")
分割"13-0-6"
(setq a "13-0-6")
(setq b (inpos "-" a)
(cons (car b) (inpos "-" (cadr b)))返回("13" "0" "6")
 楼主| 发表于 2011-10-30 16:29:22 | 显示全部楼层
本帖最后由 x_s_s_1 于 2011-10-30 16:33 编辑
cabinsummer 发表于 2011-10-30 16:19
(setvar "dimzin" 8)可以抑制rtos后面的0
你的做法复杂了,用inpos将每个G开头的字符串按-分割成两段, ...


谢谢,辛苦了,确实不用排序,我之所以用排序是因为想带着G或者VT,如果用MAX就要先判断有无G或VT,如果可以带前缀MAX就好了.要多用几个if了,我再改改,用MAX效率是高一些,我前面纠结于G或VT还有RTOS的精度问题了,再次感谢
发表于 2011-10-30 16:40:20 | 显示全部楼层
仔细看了一下楼主的例图,要得到的结果是不是:取所有组的最大的行数,取每组对应行数的各位上的最大值?
发表于 2011-10-30 16:44:27 | 显示全部楼层
x_s_s_1 发表于 2011-10-30 16:29
谢谢,辛苦了,确实不用排序,我之所以用排序是因为想带着G或者VT,如果用MAX就要先判断有无G或VT,如果 ...

max只能用于数值
(mapcar 'atof '("1.2" "0.5" "0.2"))可以将字符串表变成数值表(1.2 0.5 0.2)
将此表加上前缀max可以组成一个新表(cons 'max (mapcar 'atof '("1.2" "0.5" "0.2")))返回(max 1.2 0.5 0.2)。此时仅为一个表,要求值就得在前面加上eval才能返回最大值1.2。
排序算法的效率是很低的,这个你要是学过数据结构就应该知道,况且你排序前还是做了很多预处理,也不是一次到位。

点评

实验了一下,排序确实慢很多,谢谢  发表于 2011-10-30 17:06
 楼主| 发表于 2011-10-30 17:04:10 | 显示全部楼层
本帖最后由 x_s_s_1 于 2011-10-30 17:08 编辑
yjr111 发表于 2011-10-30 16:40
仔细看了一下楼主的例图,要得到的结果是不是:取所有组的最大的行数,取每组对应行数的各位上的最大值?


这个您的表述和我的想法可能相同,但是我对您的表述存在歧解,对应例图来看,组写为一(其余类推),行写为1(其余类推),每行的第一个数据写为a(其余类推),就是一1a,二1a,三1a对比,一1b,二1b,三1b对比,得到(一、二、三的)1maxa-maxb,(一、二、三的)2maxa-maxb(其余类推)。
发表于 2011-10-30 17:12:15 | 显示全部楼层
本帖最后由 cabinsummer 于 2011-10-31 21:11 编辑

任意分割字符串函数
  1. (defun inpos(sep str / pos prestr russtr)
  2.   (while (setq pos (vl-string-search sep str))
  3.       (setq prestr (substr str 1 pos))
  4.       (setq str (substr str (+ pos 1 (strlen sep))))
  5.       (setq russtr (append russtr (list prestr)))
  6.   )
  7.   (setq russtr (append russtr (list str)))
  8. )

这样你也就可以一次将"13-0-6"分割了。
需要说明的是,如果sep为空字符串,函数将进入死循环。
(inpos "-" "13-0-6")返回("13" "0" "6"),祝楼主好运!


您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-26 17:42 , Processed in 0.163455 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表