明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 5284|回复: 24

求各路高手帮小弟学一个计算式程序

  [复制链接]
发表于 2007-7-21 11:53 | 显示全部楼层 |阅读模式

求各路高手帮小弟学一个计算式程序(lisp)

功能如下:

假设在CAD中输入一个数学式子1):1+4+5*2+(5+5)/2+[(6+6)/2+(5+5)/2]

利用(lisp)程序中的命令js(计算的第一个字母)得出该式子的结果

(1):1+4+5*2+(5+5)/2+[(6+6)/2+(5+5)/2]=31

谢谢高手们帮帮忙..........

 

发表于 2007-7-21 12:09 | 显示全部楼层

这个问题很有意思,

我想按照运算符分级的思路(层层剥皮)是可以。

发表于 2007-7-21 12:22 | 显示全部楼层

"{" "[" "]" "}" 之类的要全替换成小括号"(" ")"

CAD中本来就有CAL命令 

到了lisp中成了函数 (C:CAL 字符表达式)

试试是你想要的吧~

还有就是调用VBA中的的eval方法来计算

在VBS,js中也有eval函数也可以用vlisp调用的

发表于 2007-7-21 13:46 | 显示全部楼层

三楼说的不错,CAD自带CAL命令。

如果你想编程实现,那就用需要用到类似于实现lisp编辑器的功能,对括号的判断和运算符的移位处理。

发表于 2007-7-21 14:43 | 显示全部楼层

这个题目有挑战性。

我以前也有这个想法。

因为用cal的方法或者smallVBA的方法速度上要打一个很大的折扣,特别是VBS,我以前曾经做过试验,对于同一个计算表达式,如果用VBS的方法求,速度要比翻译成lisp的函数慢上100倍。

CAL也没有翻译成lisp的函数的快。而且对于角的度量单位来说,CAL用的是角度,而不是弧度,要转换,很不方便。

当然计算量不大的情况下可以CAL和VBS都可以。如果运算达到上万次就不太适用了。

希望大家共同把这个难题完成。

发表于 2007-7-21 17:17 | 显示全部楼层
好主意,那我们就开始挑战吧。。。
发表于 2007-7-21 19:48 | 显示全部楼层
highflybir发表于2007-7-21 14:43:00这个题目有挑战性。我以前也有这个想法。因为用cal的方法或者smallVBA的方法速度上要打一个很大的折扣,特别是VBS,我以前曾经做过试验,对于同一个计算表达式,如果用VBS的方法求,速度要比翻

在CAD里手动输入上万次的运算不大现实,其实cal已经足够用了

至于角度单位可以自己写程序处理一下,再调用cal

发表于 2007-7-21 23:12 | 显示全部楼层
本帖最后由 作者 于 2007-7-21 23:14:28 编辑

你没能明白我的意思。

有些情况是可能重复运算某个表达式一万 次以上,

譬如,我们得到一个: x^2-sin(x)+[(x-x^2+exp(x))*2-2]之类的复杂表达式,这里x是个变量,要对这个变量计算万 次以上的值时 ,cal就不够用了。

楼主的情况跟这个类似,也都可以用lisp函数来表达。

在很多语言里面,都能把表达式直接翻译成函数,但是lisp中没有,所以我希望能完成这个挑战。

发表于 2007-7-23 21:03 | 显示全部楼层
本帖最后由 作者 于 2007-7-23 21:04:28 编辑

我先起个头,发一个我刚写好的函数~
事实上它的处理速度还是远比不上cal的~
就算是转化之后的格式用eval调用也与cal不相上下,
这一点足够让这个程序找不到实用性~
因为这只是eval函数的速率的问题了!
看看算法也就行了,以后你可能用的
  1. ;;;分离出变量与函数
  2. (defun format1 (str / char funs lastfun lst tmp lastchar)
  3.   (setq funs '("+" "-" "*" "/" "^" "%" "(" ")"))
  4.   (setq tmp "")
  5.   (while (/= str "")
  6.     (setq char (substr str 1 1))
  7.     (setq str (substr str 2))
  8.     (if (and (member char funs)
  9.       ;;负号特别处理
  10.       (not (and lastfun (/= lastfun ")") (= char "-")))
  11.       ;;"e"科学计数法特别处理
  12.       (not (and lastchar (or (= char "-") (= char "+"))))
  13. )
  14.       (setq lst      (vl-list* char tmp lst)
  15.      tmp      ""
  16.      lastfun  char
  17.      lastchar nil
  18.       )
  19.       (setq tmp      (strcat tmp char)
  20.      lastfun  nil
  21.      lastchar (if (= (strcase char) "E")
  22.          t
  23.        )
  24.       )
  25.     )
  26.   )
  27.   (vl-remove "" (reverse (cons tmp lst)))
  28. )
  29. ;;;带return的apply
  30. (defun Fsxm-Apply ($Sym $Lst / $$ return $rt)
  31.   (defun Return (var) (setq Return nil) (setq $$ var) (exit))
  32.   (setq $rt (vl-catch-all-apply $Sym $Lst))
  33.   (if Return $rt $$)
  34. )
  35. ;;递归处理括号
  36. (defun format2 (lst / a i lst2 nlst tmp var)
  37.   (setq i 0)
  38.   (while lst
  39.     (setq a (car lst))
  40.     (setq lst (cdr lst))
  41.     (setq i (1+ i))
  42.     (cond ((= a "(")
  43.     (setq var (fsxm-apply 'format2 (list lst)))
  44.     (repeat (car var) (setq lst (cdr lst)))
  45.     (setq i (+ i (car var)))
  46.     (setq nlst (cons (cadr var) nlst))
  47.     (setq tmp (cons (cadr var) tmp))
  48.    )
  49.    ((= a ")")
  50.     (return (list i (reverse tmp)))
  51.    )
  52.    (t
  53.     (setq tmp (cons a tmp))
  54.     (setq nlst (cons a nlst))
  55.    )
  56.     )
  57.   )
  58.   (reverse nlst)
  59. )
  60. ;;递归转化计算式格式
  61. (defun format3 (lst funs / lasta nlst tmp fun)
  62.   (foreach a lst
  63.     (cond ((setq fun (assoc a funs))
  64.     (setq tmp (list lasta (cadr fun)))
  65.    )
  66.    (t
  67.     (if (listp a)
  68.       (setq a (format3 a funs))
  69.     )
  70.     (if tmp
  71.       (setq lasta (reverse (cons a tmp))
  72.      nlst  (cons lasta (cdr nlst))
  73.      tmp  nil
  74.       )
  75.       (setq lasta a
  76.      nlst  (cons lasta nlst)
  77.       )
  78.     )
  79.    )
  80.     )
  81.   )
  82.   (reverse nlst)
  83. )
  84. ;;递归处理掉多余的括号,
  85. ;;常量str->浮点数real 变量str->符号sym
  86. (defun format4 (lst)
  87.   (mapcar '(lambda (a / x)
  88.       (cond ((listp a)
  89.       (if (listp (car a))
  90.         (format4 (car a))
  91.         (format4 a)
  92.       )
  93.      )
  94.      ((= (type a) 'str)
  95.       (or (setq x (distof a))
  96.    (setq x (read a))
  97.       )
  98.       x
  99.      )
  100.      (t a)
  101.       )
  102.     )
  103.    lst
  104.   )
  105. )
  106. (defun trans_format (str / lst)
  107.   ;;预处理 去空字符&转括号
  108.   (setq str (vl-string-translate "{[]}\t\n" "(())  " str))
  109.   (setq str (vl-list->string (vl-remove 32 (vl-string->list str))))
  110.   ;;分离出变量与函数
  111.   (setq lst (format1 str))
  112.   ;;递归处理括号
  113.   (setq lst (format2 lst))
  114.   ;;优先计算  开方
  115.   (setq lst (format3 lst '(("^" expt))))
  116.   ;;再次计算  乘 除 取模
  117.   (setq lst (format3 lst '(("*" *) ("/" /) ("%" rem))))
  118.   ;;最后计算 加减
  119.   (setq lst (format3 lst '(("+" +) ("-" -))))
  120.   ;;后处理
  121.   (car (format4 lst))
  122. )
  123. ;;测试1:
  124. (setq str "(1/2+22*2-5)/3^3+2-1e+2*5")
  125. (defun c:t1 ()
  126.   (eval (trans_format str))
  127. )
  128. (defun c:t2 ()
  129.   (c:cal str)
  130. )
  131. ;;测试2:
  132. (defun c:t3 ()
  133.   (setq trans_lst (trans_format str))
  134.   (repeat 10000
  135.     (eval trans_lst)
  136.   )
  137. )
  138. (defun c:t4 ()
  139.   (repeat 10000
  140.     (c:cal str)
  141.   )
  142. )
发表于 2007-7-23 21:48 | 显示全部楼层
对诸如sin、int等函数不好辨别处理啊!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-6 02:32 , Processed in 0.184766 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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