7,763
社区成员
发帖
与我相关
我的任务
分享
'Remove parentheses in a math expression
Private Function RemParen(ByVal strInput As String) As String
Dim strResult As String
Dim strIn As String '括号里的表达式'
Dim strOut As String '括号外的表达式'
Dim strtmp() As String, i As Long '用于分割'
Dim lngStartPos As Long, lngEndPos As Long, lngRightParen As Long, lngLeftParen As Long
Dim strEndSign As String '每段括号后最近的加号或等号'
'把减号替换成+-以便分割
strInput = Replace(strInput, "-", "+-")
lngStartPos = 1
'逐括号分段处理'
Do
'*****取得括号内部分和括号外部分'
lngRightParen = InStr(lngStartPos, strInput, ")")
lngLeftParen = InStr(lngStartPos, strInput, "(")
strIn = Mid(strInput, lngLeftParen + 1, lngRightParen - lngLeftParen - 1)
If lngLeftParen = lngStartPos Then
'括号部分在前:(x^2+2)5x这种形式的'
lngEndPos = FindEndSign(lngRightParen, strInput, strEndSign)
strOut = Mid(strInput, lngRightParen + 1, lngEndPos - lngRightParen - 1)
Else
'括号部分在后: 2x(3-4x)这种形式的'
strOut = Mid(strInput, lngStartPos, lngLeftParen - lngStartPos)
lngEndPos = lngRightParen + 1
strEndSign = Mid(strInput, lngEndPos, 1)
End If
' Debug.Print strIn, strOut, strEndSign
'*****把括号内部分和括号外部分相乘'
strtmp = Split(strIn, "+")
For i = 0 To UBound(strtmp)
strResult = strResult & MplyStr(strOut, strtmp(i)) & "+"
Next i
'*****把最后一个字符弄对'
strResult = Left(strResult, Len(strResult) - 1) & strEndSign
lngStartPos = lngEndPos + 1
If strEndSign = "" Then Exit Do
Loop
strResult = Replace(strResult, "+-", "-")
RemParen = strResult
' Debug.Print strInput
' Debug.Print strResult
End Function
'从str1的lngStartPos开始找到其后最近的加号或等号'
'返回值是找到的等号或加号的位置,找不到则返回str1的长度加1'
'找到的等号或加号存在ByRef参数strEndSign里返回,找不到则返回""'
Private Function FindEndSign(ByVal lngStartPos As Long, ByVal str1 As String, _
ByRef strEndSign As String) As Long
Dim lngAdd As Long, lngEqual As Long
lngAdd = InStr(lngStartPos, str1, "+")
lngEqual = InStr(lngStartPos, str1, "=")
If lngAdd = 0 Then lngAdd = 10000
If lngEqual = 0 Then lngEqual = 10000
If lngAdd < lngEqual Then
strEndSign = "+"
FindEndSign = lngAdd
Else
strEndSign = "="
FindEndSign = lngEqual
End If
If FindEndSign = 10000 Then
strEndSign = ""
FindEndSign = Len(str1) + 1
End If
End Function
'把str1和str2所表示的表达式"相乘",并把相乘的结果输出'
'注意:str1,str2都只能是含有0个或1个变量的单项式!变量只能是x!
'可处理的最复杂情况是:MplyStr("3x^2", "-2x") = "-6x^3"
Private Function MplyStr(str1 As String, str2 As String) As String
Dim strResult As String
Dim i As Long, j As Long
Dim str1suf As String, str2suf As String '后缀'
AnaStr str1, i, str1suf
AnaStr str2, j, str2suf
If str1suf <> "" And str2suf <> "" Then
strResult = (i * j) & "x^" & (GetPower(str1suf) + GetPower(str2suf))
Else
strResult = (i * j) & str1suf & str2suf
End If
MplyStr = strResult
End Function
'分析str1,拆分它的数字部分和变量部分'
'数字部分返回到ByRef参数lng1里;变量部分返回到ByRef参数str1suf里'
'比如 str1="-x^2", lng1 = -1, str1suf = "x^2"
Private Sub AnaStr(ByVal str1 As String, ByRef lng1 As Long, ByRef str1suf As String)
Dim strtmp() As String
On Error GoTo AnaStr_ErrHandler
str1suf = ""
strtmp = Split(str1, "x")
strtmp(0) = Replace(strtmp(0), "+-", "-")
If strtmp(0) = "" Then
lng1 = 1
ElseIf strtmp(0) = "-" Then
lng1 = -1
Else
lng1 = strtmp(0)
End If
str1suf = "x" & strtmp(1)
Exit Sub
AnaStr_ErrHandler:
If Err.Number = 9 Then
'Subscript out of range
'没有x
Resume Next
Else
Stop
Resume
End If
End Sub
'从带幂的字符串得到对应的幂次
'GetPower("x^2") = 2, GetPower("x") = 1
Private Function GetPower(strPower As String) As Long
If strPower = "x" Then
GetPower = 1
Else
GetPower = Right(strPower, Len(strPower) - 2)
End If
End Function
Public Sub test_RemParen()
Debug.Assert RemParen("2x(3-4x)+5(8+3x+8x^2)=(x^2+2)5x-3x^2(2x-7)") = "6x-8x^2+40+15x+40x^2=5x^3+10x-6x^3+21x^2"
Debug.Assert RemParen("2x(3-4x)") = "6x-8x^2"
Debug.Assert RemParen("5(8+3x+8x^2)") = "40+15x+40x^2"
Debug.Assert RemParen("(x^2+2)5x") = "5x^3+10x"
Debug.Assert RemParen("-3x^2(2x-7)") = "-6x^3+21x^2"
End Sub
Public Sub Test_MplyStr()
Debug.Assert MplyStr("2", "3") = "6"
Debug.Assert MplyStr("2", "-4x") = "-8x"
Debug.Assert MplyStr("5", "8x^2") = "40x^2"
Debug.Assert MplyStr("5x", "2") = "10x"
Debug.Assert MplyStr("3x^2", "7") = "21x^2"
Debug.Assert MplyStr("3x^2", "2x") = "6x^3"
Debug.Assert MplyStr("5x", "x^2") = "5x^3"
End Sub
Public Sub test_AnaStr()
Dim lng1 As Long
Dim str1suf As String
AnaStr "2", lng1, str1suf
Debug.Assert lng1 = 2
Debug.Assert str1suf = ""
AnaStr "-7", lng1, str1suf
Debug.Assert lng1 = -7
Debug.Assert str1suf = ""
AnaStr "x", lng1, str1suf
Debug.Assert lng1 = 1
Debug.Assert str1suf = "x"
AnaStr "-x", lng1, str1suf
Debug.Assert lng1 = -1
Debug.Assert str1suf = "x"
AnaStr "2x", lng1, str1suf
Debug.Assert lng1 = 2
Debug.Assert str1suf = "x"
AnaStr "-2x", lng1, str1suf
Debug.Assert lng1 = -2
Debug.Assert str1suf = "x"
AnaStr "-2x^2", lng1, str1suf
Debug.Assert lng1 = -2
Debug.Assert str1suf = "x^2"
AnaStr "x^2", lng1, str1suf
Debug.Assert lng1 = 1
Debug.Assert str1suf = "x^2"
AnaStr "-x^2", lng1, str1suf
Debug.Assert lng1 = -1
Debug.Assert str1suf = "x^2"
End Sub