明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3158|回复: 4

[原创]用VB实现字符形式的表达式的计算.

[复制链接]
发表于 2003-10-29 10:04 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2003-10-29 11:07:52 编辑

有时需要计算以字符串保存的数学表达式,又没有直接的函数可供调用,但可以根据表达式的运算规则编制这样的模块程序来实现.
原理:
1.建立两个堆栈,并自左至右扫描表达式;
2.如遇操作数,一律压入堆栈;
3.如遇操作符,如优于栈顶操作符,则压入堆栈,否则以操作符栈顶的操作符计算数据栈顶的两个操作数,以此类推.

CalExp类(3K)


主函数如下:

  1. Option Explicit

  2. '
  3. '
  4. '---------------------------------
  5. 'Class  :CalExp
  6. '
  7. 'Program:zeng29
  8. 'Date   :2003/10/25
  9. 'Ver.   :1.0.0
  10. '
  11. '---------------------------------
  12. '
  13. '

  14. Private Const cPi = 3.14159265358979
  15. Private Const cE = 2.71828182845905

  16. Public Function CalExpression(sExp As String) As Variant
  17.     Dim ReadPoint As Integer, i As Integer, j As Integer, sChar As String
  18.     Dim sOpArray As Variant, iOpPower As Variant, sFunArray As Variant
  19.     Dim DataStack() As Double, OpStack() As String
  20.     Dim sCurOP As String, iIndex As Integer, iFlag As Integer, sPara As String
  21.     Dim sFunName As String, vRet As Variant
  22.     Dim dData1 As Variant, dData2 As Variant, sOp As String
  23.    
  24.     '初始化...
  25.     ReDim DataStack(0)
  26.     ReDim OpStack(0)
  27.     sOpArray = Array("+", "-", "*", "/", "^", "%")
  28.     iOpPower = Array(1, 1, 3, 3, 4, 2)
  29.     sFunArray = Array("sin", "cos", "tan", "asin", "acos", "atn", "abs", "ln", "pi", "e")
  30.     ReadPoint = 1
  31.    
  32.     While ReadPoint <= Len(sExp)
  33.         sChar = Mid(sExp, ReadPoint, 1)
  34.         
  35.         '运用递归处理"( )"...
  36.         If sChar = "(" Then
  37.             sPara = ""
  38.             For i = ReadPoint To Len(sExp)
  39.                 sChar = Mid(sExp, i, 1)
  40.                 If sChar = "(" Then
  41.                     iFlag = iFlag + 1
  42.                 ElseIf sChar = ")" Then
  43.                     iFlag = iFlag - 1
  44.                     If iFlag = 0 Then
  45.                         vRet = CalExpression(sPara)
  46.                         If IsNumeric(vRet) Then
  47.                             PushToStc DataStack, vRet
  48.                             ReadPoint = i + 1
  49.                             Exit For
  50.                         Else
  51.                             CalExpression = vRet
  52.                             Exit Function
  53.                         End If
  54.                     End If
  55.                 End If
  56.                 If iFlag <> 0 And i <> ReadPoint Then sPara = sPara & sChar
  57.             Next i
  58.             If iFlag <> 0 Then
  59.                 CalExpression = "错误的表达式:括号不成对!"
  60.                 Exit Function
  61.             End If
  62.         
  63.         '读取数值...
  64.         ElseIf IsNumeric(sChar) Or sChar = "." Or (ReadPoint = 1 And (sChar = "+" Or sChar = "-")) Then
  65.             sPara = ""
  66.             For i = ReadPoint To Len(sExp)
  67.                 sChar = Mid(sExp, i, 1)
  68.                 If IsNumeric(sChar) Or sChar = "." Or (i = 1 And (sChar = "+" Or sChar = "-")) Then
  69.                     sPara = sPara & sChar
  70.                 ElseIf IsNumeric(sPara) Then
  71.                     PushToStc DataStack, sPara
  72.                     ReadPoint = i
  73.                     Exit For
  74.                 Else
  75.                     CalExpression = "非法的表达式:" & sPara & sChar
  76.                     Exit Function
  77.                 End If
  78.             Next i
  79.             If i > Len(sExp) And IsNumeric(sPara) Then PushToStc DataStack, sPara
  80.             ReadPoint = i
  81.         Else
  82.             vRet = GetIndex(sOpArray, sChar)
  83.             
  84.             '读取操作符...
  85.             If vRet <> "Null" Then
  86. ReCheck:
  87.                 If PopFromStc(OpStack, False) = "Null" Then
  88.                     PushToStc OpStack, sChar
  89.                 Else
  90.                     If iOpPower(vRet) > iOpPower(GetIndex(sOpArray, PopFromStc(OpStack, False))) Then
  91.                         PushToStc OpStack, sChar
  92.                     Else
  93.                         dData2 = PopFromStc(DataStack)
  94.                         dData1 = PopFromStc(DataStack)
  95.                         sOp = PopFromStc(OpStack)
  96.                         PushToStc DataStack, ProCal(dData1, dData2, sOp)
  97.                         GoTo ReCheck
  98.                     End If
  99.                 End If
  100.             Else
  101.             
  102.                 '读取函数...
  103.                 vRet = Asc(LCase(sChar))
  104.                 If vRet >= Asc("a") And vRet <= Asc("z") Then
  105.                     sFunName = ""
  106.                     For i = ReadPoint To Len(sExp)
  107.                         sChar = Mid(sExp, i, 1)
  108.                         vRet = Asc(LCase(sChar))
  109.                         If vRet >= Asc("a") And vRet <= Asc("z") Then
  110.                             sFunName = sFunName & sChar
  111.                         ElseIf sChar = "(" Then
  112.                             vRet = GetIndex(sFunArray, sFunName)
  113.                             If vRet = "Null" Then
  114.                                 CalExpression = "不知道的函数:" & sFunName
  115.                                 Exit Function
  116.                             End If
  117.                             sPara = ""
  118.                             iFlag = 0
  119.                             For j = i To Len(sExp)
  120.                                 sChar = Mid(sExp, j, 1)
  121.                                 If sChar = "(" Then
  122.                                     iFlag = iFlag + 1
  123.                                 ElseIf sChar = ")" Then
  124.                                     iFlag = iFlag - 1
  125.                                     If iFlag = 0 Then
  126.                                         vRet = CallFun(sFunName, sPara)
  127.                                         sFunName = ""
  128.                                         If IsNumeric(vRet) Then
  129.                                             PushToStc DataStack, vRet
  130.                                             ReadPoint = j + 1
  131.                                             GoTo ReadNext
  132.                                         Else
  133.                                             CalExpression = vRet
  134.                                             Exit Function
  135.                                         End If
  136.                                     End If
  137.                                 End If
  138.                                 If iFlag <> 0 And (j <> i) Then sPara = sPara & sChar
  139.                             Next j
  140.                             If iFlag <> 0 Then
  141.                                 CalExpression = "错误的表达式:括号不成对!"
  142.                                 Exit Function
  143.                             End If
  144.                         End If
  145.                         If i = Len(sExp) And sFunName <> "" Then
  146.                             CalExpression = "函数的用法:函数名([参数])"
  147.                             Exit Function
  148.                         End If
  149.                     Next i
  150.                 Else
  151.                     CalExpression = "错误的表达式:不知道的操作符:" & sChar
  152.                     Exit Function
  153.                 End If
  154.             End If
  155.             ReadPoint = ReadPoint + 1
  156.         End If
  157. ReadNext:
  158.     Wend
  159.    
  160.     '运算最终结果...
  161.     If UBound(DataStack) = 1 Then
  162.         CalExpression = PopFromStc(DataStack)
  163.     Else
  164.         Do
  165.             dData2 = PopFromStc(DataStack)
  166.             dData1 = PopFromStc(DataStack)
  167.             sOp = PopFromStc(OpStack)
  168.             If IsNumeric(dData1) And IsNumeric(dData2) And sOp <> "Null" Then
  169.                 PushToStc DataStack, ProCal(dData1, dData2, sOp)
  170.             Else
  171.                 CalExpression = "非法的表达式!"
  172.                 Exit Function
  173.             End If
  174.         Loop Until PopFromStc(OpStack, False) = "Null"
  175.         CalExpression = PopFromStc(DataStack)
  176.     End If
  177. End Function

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1威望 +2 金钱 +10 贡献 +5 激情 +10 收起 理由
mccad + 2 + 10 + 5 + 10 【好评】好程序

查看全部评分

发表于 2003-11-29 21:49 | 显示全部楼层
怎么用?
我导入模块后写
k="2*3"
msgbox calexpression(k)
不能运行,显示:函数未定义。
我把calex类模块的内容全部复制到自己建立的模块1时,就可以使用了。
发表于 2003-12-1 15:01 | 显示全部楼层
这与数据结构里面的算符优先算法很相似阿~~~~
发表于 2010-7-30 11:50 | 显示全部楼层
cvbndvhcnddfd
发表于 2018-2-3 20:35 | 显示全部楼层
表达式可用于CAD的常用计算中,好!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-23 20:32 , Processed in 0.393433 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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