| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 752 人关注过本帖
标题:混和计算
只看楼主 加入收藏
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4947
专家分:30084
注 册:2008-10-15
结帖率:100%
收藏
 问题点数:0 回复次数:3 
混和计算
已知BUG。
1、表达式第一个字符是 运算符时,程序报错。
2、多个加号连在一起,程序会忽略掉。


提供给大家参考,希望能有人优化一下。

程序代码:
Option Explicit

Private Sub Command1_Click()
Label1.Caption = "=" & 计算(Text1.Text)
End Sub

Public Function 计算(cs As String) As String

Dim i As Long, j As Long
Dim k As String
Dim k1 As String, k2 As String
Dim k3 As String, k4 As String
Dim bj As Boolean
Dim yy As Long

k4 = cs

'处理括号
If InStr(1, cs, "(") > 0 And InStr(1, cs, ")") > 0 Then '含括号继续
    i = InStrRev(k4, "(")           '从右向左
    Do While i > 0                  '找到左括号
        j = InStr(i, k4, ")")       '寻找最近的右括号
        If j = 0 And i > 0 Then     '没找到
            k4 = "Err"              '错误
            Exit Do
        End If
       
        k4 = Left(k4, i - 1) & 计算(Mid(k4, i + 1, j - i - 1)) & Mid(k4, j + 1)     '找到后,计算括号内容
        i = InStrRev(k4, "(")       '继续查找
        'Debug.Print k4              '显示每一步处理后表达式的变化
    Loop
End If

If InStr(1, k4, "Err") Then     '如果通过计算后,出现了Err ,则立即报Err 给上一层
    计算 = "Err"
    Exit Function
End If

If InStr(1, k4, "(") > 0 Or InStr(1, k4, ")") > 0 Then      '如果通过上面处理后,还含有括号,说明括号不配对
    计算 = "Err"
    Exit Function
End If

For i = 1 To Len(k4)        '从第一个字符向向搜索
    k1 = Mid(k4, i, 1)

    Select Case k1
        Case "*"         '
            If k3 <> "" Then
                '先计算,再把结果给K2
                k2 = 计算1(k2, k3, yy)
            End If
            k3 = ""             '第二个数为空
            bj = True           '需要算第二个数
            yy = 3              '运算符是 3
        Case "/"
            If k3 <> "" Then
                '先计算,再把结果给K2
                k2 = 计算1(k2, k3, yy)
            End If
            k3 = ""             '第二个数为空
            bj = True           '需要算第二个数
            yy = 4              '运算符是 3
        Case "+", "-"           '要运行,然后把结果给K
            '先计算,再把结果给K2
            If Mid(k4, i - 1, 1) <> "E" Then            '如果不是科学记数法的符号,
                If yy = 3 Or yy = 4 Then
                    k2 = 计算1(k2, k3, yy)
                    k3 = ""
                    yy = 0
                    bj = False
                End If
                k = k & k2 & k1
                k2 = ""
            Else                    '否则保存
                If bj Then
                    k3 = k3 & k1
                Else
                    k2 = k2 & k1
                End If
            End If
        Case "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "E", "."             '允许的合法数据
            If bj Then
                k3 = k3 & k1
            Else
                k2 = k2 & k1
            End If
    End Select
Next i
    If yy = 3 Or yy = 4 Then
        k2 = 计算1(k2, k3, yy)
    End If

k = k & k2

k4 = k

If InStr(1, k4, "Err") Then     '如果通过计算后,出现了Err ,则立即报Err 给上一层
    计算 = "Err"
    Exit Function
End If

k2 = "": k3 = "": k1 = ""       '临时变量全为空
yy = 0
bj = False                      '设置为没有运算过,如果少了一句,会吃掉第一个数据

For i = 1 To Len(k4)        '从第一个字符向向搜索
    k1 = Mid(k4, i, 1)
   
    Select Case k1
        Case "+"         '
            If Mid(k4, i - 1, 1) <> "E" Then
                If k3 <> "" Then
                    '先计算,再把结果给K2
                    k2 = 计算1(k2, k3, yy)
                End If
                k3 = ""             '第二个数为空
                bj = True           '需要算第二个数
                yy = 1              '运算符是 3
            Else
                If bj Then
                    k3 = k3 & k1
                Else
                    k2 = k2 & k1
                End If
            End If
        Case "-"           '
            If Mid(k4, i - 1, 1) <> "E" Then
                If k3 <> "" Then
                    '先计算,再把结果给K2
                    k2 = 计算1(k2, k3, yy)
                End If
                k3 = ""             '第二个数为空
                bj = True           '需要算第二个数
                yy = 2              '运算符是 2
            Else
                If bj Then
                    k3 = k3 & k1
                Else
                    k2 = k2 & k1
                End If
            End If
        Case "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", "E"
            If bj Then
                k3 = k3 & k1
            Else
                k2 = k2 & k1
            End If
    End Select
Next i
    k2 = 计算1(k2, k3, yy)

计算 = k2


End Function

Public Function 计算1(cs1 As String, cs2 As String, cs3 As Long) As String

If IsNumeric(cs1) And IsNumeric(cs2) Then

    If InStr(1, cs1, "Err") > 0 Or InStr(1, cs2, "Err") > 0 Then
        计算1 = "Err"
        Exit Function
    End If
       
    Select Case cs3
        Case 0                                  '运算符为0,直接返回第一个参数
            计算1 = cs1
        Case 1                                  '
            计算1 = Val(cs1) + Val(cs2)
        Case 2                                  '
            计算1 = Val(cs1) - Val(cs2)
        Case 3                                  '
            计算1 = Val(cs1) * Val(cs2)
        Case 4                                  '
            计算1 = Val(cs1) / Val(cs2)
    End Select
Else
    计算1 = "Err"
End If
End Function



搜索更多相关主题的帖子: 计算 优化 表达式 color 
2010-03-24 14:35
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4947
专家分:30084
注 册:2008-10-15
收藏
得分:0 
支持 表达式混和计算

如:
6*(5+6)+5*10

主函数是递归调用的,数据类型在 数字 和 字符串之间变来变去。

授人于鱼,不如授人于渔
早已停用QQ了
2010-03-24 14:53
yuk_yu
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:334
专家分:134
注 册:2009-3-16
收藏
得分:0 
回复 2楼 风吹过b
1*(4-5) 出错
2010-03-31 11:44
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4947
专家分:30084
注 册:2008-10-15
收藏
得分:0 
找到原因了.回头再改.

1\计算部分,运算符为0 时,不需要判断第二个参数类型.

2\没有处理 正负号 造成.


授人于鱼,不如授人于渔
早已停用QQ了
2010-04-02 17:23
快速回复:混和计算
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.038270 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved