这个可以参考微软 Microsoft Student 2009 里面学生计算器的做法。 包括表达式化简,解方程,函数作图等等。大概看了下 .NET写的,没有混淆
Dim a, b, c, d, e, x As String Dim f As Integer a = "2x(3-4x)+5(8+3x+8x^2)" f = InStr(1, a, "+") b = Left(a, f - 1) 'b=2x(3-4x) c = Mid(a, f + 1, 12) 'c=5(8+3x+8x^2) Debug.Print c d = Mid(b, 4, 1) 'd=3 f = Val(d) * Val(Mid(b, 1, 1)) e = f & "x" 'e=6x f = Val(Mid(b, 1, 1)) * Val(Mid(b, 6, 1)) e = e & "-" & f & "x ^ 2" & "+" 'e=6x-8x^2+ a = Mid(c, 3, 1) b = Mid(c, 1, 1) f = Val(a) * Val(b) e = e & f & "+" a = Mid(c, 5, 1) f = Val(a) * Val(b) e = e & f & "x" & "+" a = Mid(c, 8, 1) f = Val(a) * Val(b) e = e & f & "x^2" Debug.Print eDim a, b, c, d, e, x As String Dim f As Integer a = "2x(3-4x)+5(8+3x+8x^2)" f = InStr(1, a, "+") b = Left(a, f - 1) 'b=2x(3-4x) c = Mid(a, f + 1, 12) 'c=5(8+3x+8x^2) Debug.Print c d = Mid(b, 4, 1) 'd=3 f = Val(d) * Val(Mid(b, 1, 1)) e = f & "x" 'e=6x f = Val(Mid(b, 1, 1)) * Val(Mid(b, 6, 1)) e = e & "-" & f & "x ^ 2" & "+" 'e=6x-8x^2+ a = Mid(c, 3, 1) b = Mid(c, 1, 1) f = Val(a) * Val(b) e = e & f & "+" a = Mid(c, 5, 1) f = Val(a) * Val(b) e = e & f & "x" & "+" a = Mid(c, 8, 1) f = Val(a) * Val(b) e = e & f & "x^2" Debug.Print e 真是无聊了,呵呵
s = "2x(3-4x)+5(8+3x+8x^2)=(x^2+2)5x-3x^2(2x-7)" s = "6x-8x^2+40+15x+40x^2=5x^3+10x-6x^3+21x^2" 变好了,
'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 '每段括号后最近的加号或等号'
' 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
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 SubPublic 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 SubPublic Sub test_AnaStr() Dim lng1 As Long Dim str1suf As String
包括表达式化简,解方程,函数作图等等。大概看了下 .NET写的,没有混淆
Dim f As Integer
a = "2x(3-4x)+5(8+3x+8x^2)"
f = InStr(1, a, "+")
b = Left(a, f - 1) 'b=2x(3-4x)
c = Mid(a, f + 1, 12) 'c=5(8+3x+8x^2)
Debug.Print c
d = Mid(b, 4, 1) 'd=3
f = Val(d) * Val(Mid(b, 1, 1))
e = f & "x" 'e=6x
f = Val(Mid(b, 1, 1)) * Val(Mid(b, 6, 1))
e = e & "-" & f & "x ^ 2" & "+" 'e=6x-8x^2+
a = Mid(c, 3, 1)
b = Mid(c, 1, 1)
f = Val(a) * Val(b)
e = e & f & "+"
a = Mid(c, 5, 1)
f = Val(a) * Val(b)
e = e & f & "x" & "+"
a = Mid(c, 8, 1)
f = Val(a) * Val(b)
e = e & f & "x^2"
Debug.Print eDim a, b, c, d, e, x As String
Dim f As Integer
a = "2x(3-4x)+5(8+3x+8x^2)"
f = InStr(1, a, "+")
b = Left(a, f - 1) 'b=2x(3-4x)
c = Mid(a, f + 1, 12) 'c=5(8+3x+8x^2)
Debug.Print c
d = Mid(b, 4, 1) 'd=3
f = Val(d) * Val(Mid(b, 1, 1))
e = f & "x" 'e=6x
f = Val(Mid(b, 1, 1)) * Val(Mid(b, 6, 1))
e = e & "-" & f & "x ^ 2" & "+" 'e=6x-8x^2+
a = Mid(c, 3, 1)
b = Mid(c, 1, 1)
f = Val(a) * Val(b)
e = e & f & "+"
a = Mid(c, 5, 1)
f = Val(a) * Val(b)
e = e & f & "x" & "+"
a = Mid(c, 8, 1)
f = Val(a) * Val(b)
e = e & f & "x^2"
Debug.Print e
真是无聊了,呵呵
s = "6x-8x^2+40+15x+40x^2=5x^3+10x-6x^3+21x^2"
变好了,
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 SubPublic 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 SubPublic 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