VB利用堆栈实现表达式计算

来源:互联网 发布:hbase java api maven 编辑:程序博客网 时间:2024/06/10 18:56
VB利用堆栈实现表达式计算
    前几天对上学期老师的课件进行了深入学习后,我觉得有必要写个程序实践下,验证表达式计算设计十分正确。于是诞生了如下的程序。
    需要说明一点,这里的代码都是自主设计的,未参考网上的任何代码,所以,此代码拥有完全自主知识产权。
    版权所有,转载请注明出处:SunSoft
Form1.frm文件内容:
VERSION 5.00
Begin VB.Form Form1 
   Caption         =   "表达式计算"
   ClientHeight    =   3195
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   4680
   LinkTopic       =   "Form1"
   ScaleHeight     =   3195
   ScaleWidth      =   4680
   StartUpPosition =   3  '窗口缺省
   Begin VB.TextBox Text2 
      Height          =   2415
      Left            =   2760
      MultiLine       =   -1  'True
      ScrollBars      =   2  'Vertical
      TabIndex        =   4
      Top             =   720
      Width           =   975
   End
   Begin VB.TextBox Text1 
      Height          =   2415
      Left            =   720
      MultiLine       =   -1  'True
      ScrollBars      =   2  'Vertical
      TabIndex        =   3
      Top             =   720
      Width           =   1215
   End
   Begin VB.CommandButton Command2 
      Caption         =   "Command2"
      Height          =   615
      Left            =   3840
      TabIndex        =   2
      Top             =   480
      Width           =   735
   End
   Begin VB.TextBox SourceText 
      Height          =   270
      Left            =   120
      TabIndex        =   1
      Top             =   120
      Width           =   3615
   End
   Begin VB.CommandButton Command1 
      Caption         =   "Calc"
      Height          =   300
      Left            =   3840
      TabIndex        =   0
      Top             =   120
      Width           =   735
   End
   Begin VB.Label Label2 
      Caption         =   "数字栈"
      Height          =   255
      Left            =   2040
      TabIndex        =   6
      Top             =   720
      Width           =   615
   End
   Begin VB.Label Label1 
      Caption         =   "操作符"
      Height          =   255
      Left            =   0
      TabIndex        =   5
      Top             =   720
      Width           =   615
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)  '声明
Dim opNum As New StackClass
Dim opChar As New StackClass

Private Sub Command1_Click()
    Dim sTxt As String
    Dim strNumFix As String
    Dim curChar As String
    Dim i As Long
    Dim ops1 As String, ops2 As String, opC As String
    '初始化堆栈
        opNum.Clear
        opChar.Clear
        Call UpdateShow
    '堆栈初始化结束
    sTxt = SourceText.Text
    For i = 1 To Len(sTxt)
        curChar = Mid(sTxt, i, 1)
        If IsSymbol(curChar) = True Then
            '看看数字预备区有没有
            If strNumFix <> "" Then
                opNum.Push strNumFix
                Call UpdateShow
                strNumFix = ""
            End If
redo:
            If IsHigh(curChar, opChar.Peek) = 1 Then 'if new come char is higher then push it to stack
                opChar.Push curChar '如果等级高的控制符,则进入
                Call UpdateShow
            ElseIf IsHigh(curChar, opChar.Peek) = 0 Then
                'Debug.Print "结果是:" & opNum.Pop
                'Exit Sub
                If curChar = "#" And opChar.Peek = "#" Then
                    opChar.Pop
                    Call UpdateShow
                    Debug.Print "输出结果是:" & opNum.Pop
                    Exit Sub
                End If
            ElseIf IsHigh(curChar, opChar.Peek) = -1 Then 'if low then ready to calculate
                ops2 = opNum.Pop
                Call UpdateShow
                ops1 = opNum.Pop
                Call UpdateShow
                opC = opChar.Pop
                Call UpdateShow
                opNum.Push CStr(Calc(ops1, ops2, opC))
                Call UpdateShow
                If curChar = ")" And opChar.Peek = "(" Then
                    opChar.Pop  '如果操作数是),就把(弹出来
                    Call UpdateShow
                    GoTo moveon
                End If
                GoTo redo
moveon:
            End If
        Else '非符号
            strNumFix = strNumFix & curChar
        End If
    Next i
    
End Sub

Private Sub Command2_Click()
MsgBox IsHigh("+", "+")
End Sub

Private Sub Form_Load()
Me.Show
opNum.Clear
opChar.Clear
End Sub
Function IsSymbol(ByVal strS As String) As Boolean
    IsSymbol = True
    Select Case strS
        Case "+"
        Case "-"
        Case "*"
        Case "/"
        Case "("
        Case ")"
        Case "#"
        Case Else
            IsSymbol = False
    End Select
End Function
Function IsHigh(ByVal sNew As String, ByVal sOld As String) As Integer
'1大于,-1小于,0等于
Select Case sNew
Case "+"
    Select Case sOld
        Case "("
            IsHigh = 1
            Exit Function
        Case "#"
            IsHigh = 1
            Exit Function
        Case Else
            IsHigh = -1
            Exit Function
    End Select
Case "-"
    Select Case sOld
        Case "("
            IsHigh = 1
            Exit Function
        Case "#"
            IsHigh = 1
            Exit Function
        Case Else
            IsHigh = -1
            Exit Function
    End Select
Case "*"
    Select Case sOld
        Case "("
            IsHigh = 1
            Exit Function
        Case "#"
            IsHigh = 1
            Exit Function
        Case "+"
            IsHigh = 1
            Exit Function
        Case "-"
            IsHigh = 1
            Exit Function
        Case Else
            IsHigh = -1
            Exit Function
    End Select
Case "/"
    Select Case sOld
        Case "("
            IsHigh = 1
            Exit Function
        Case "#"
            IsHigh = 1
            Exit Function
        Case "+"
            IsHigh = 1
            Exit Function
        Case "-"
            IsHigh = 1
            Exit Function
        Case Else
            IsHigh = -1
            Exit Function
    End Select
Case "("
    Select Case sOld
        Case "+"
            IsHigh = 1
            Exit Function
        Case "-"
            IsHigh = 1
            Exit Function
        Case "*"
            IsHigh = 1
            Exit Function
        Case "/"
            IsHigh = 1
            Exit Function
        Case "("
            IsHigh = 1
            Exit Function
        Case Else
            IsHigh = -1
            Exit Function
    End Select
Case ")"
    IsHigh = -1
    Exit Function
Case ""
    IsHigh = -1
    Exit Function
Case "#"
    Select Case sOld
        Case "#"
            IsHigh = 0
            Exit Function
        Case ""
            IsHigh = 1
            Exit Function
        Case "+"
            IsHigh = -1
            Exit Function
        Case "-"
            IsHigh = -1
            Exit Function
        Case "*"
            IsHigh = -1
            Exit Function
        Case "/"
            IsHigh = -1
            Exit Function
        Case ")"
            IsHigh = -1
            Exit Function
    End Select
End Select
End Function
Function Calc(ByVal op1 As String, ByVal op2 As String, ByVal options As String) As Double
On Error Resume Next
Calc = 0
Select Case options
    Case "+"
        Calc = CDbl(op1) + CDbl(op2)
    Case "-"
        Calc = CDbl(op1) - CDbl(op2)
    Case "*"
        Calc = CDbl(op1) * CDbl(op2)
    Case "/"
        Calc = CDbl(op1) / CDbl(op2)
End Select
End Function
Sub Delay(ByVal msec As Long) '函数:msec为毫秒数
DoEvents
Sleep msec
End Sub
Sub UpdateShow()
    DoEvents
    Text1.Text = opChar.ViewStack
    DoEvents
    Text2.Text = opNum.ViewStack
    DoEvents
    Call Delay(500)
End Sub
-----------------------------StackClass.cls文件内容----------------------------
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "StackClass"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Private Stack() As String
Private itemCount As Long
Private Sub Class_Initialize()
    ReDim Stack(0)
    Stack(0) = "#"
End Sub
Public Sub Push(ByVal inString As String)
    ReDim Preserve Stack(itemCount + 1)
    Stack(itemCount + 1) = inString
    itemCount = itemCount + 1
End Sub

Public Function Pop() As String
    If itemCount >= 1 Then
        Pop = Stack(itemCount)
        ReDim Preserve Stack(itemCount - 1)
        itemCount = itemCount - 1
    Else
        Pop = ""
    End If
End Function
Public Function Peek() As String
    If itemCount = 0 Then
        Peek = ""
        Exit Function
    End If
    Peek = Stack(itemCount)
End Function

Sub Clear()
    itemCount = 0
    ReDim Stack(itemCount)
    Stack(itemCount) = "#"
End Sub

Public Function Count()
    Count = itemCount
End Function
Public Function ViewStack() As String
    Dim kOut As String
    Dim i As Long
    If itemCount = 0 Then ViewStack = "": Exit Function
    For i = 1 To itemCount
        kOut = kOut & Format(i, "00") & " " & Stack(i) & vbCrLf
    Next i
    ViewStack = kOut
End Function
 
原创粉丝点击