首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

求算法——关于字符串映射替换的有关问题

2012-01-18 
求算法——关于字符串映射替换的问题比如:原字符串“(A1+D3)*A11”有如下映射关系 A1-Var1D3-Var2A11- Var3

求算法——关于字符串映射替换的问题
比如:原字符串“(A1+D3)*A11”

有如下映射关系 A1 -> Var1
  D3 -> Var2
  A11 -> Var3


转换后的字符串应为“(Var1+Var2)*Var3”

请问擅长于算法的朋友,应该实现上面的转换?谢谢!!

[解决办法]
属于基本的算术式解析,给你一段四则运算解析代码示例:

VB code
Option Base 1Dim tt(20) As String          '存放按+,-号分解出来的式子,只设定了20个Private Sub Command1_Click()    Text2.Text = handle(Text1.Text)End SubPrivate Function handle(a)                  '按括号分解式子    Dim th, th2 As String                      '存放按括号分解出来的式子    Do While True        n1 = InStr(a, "(")                          '查找        n2 = InStr(a, ")")        Select Case True            Case n1 = 0 And n2 = 0                      '没有括号                Exit Do                Case n1 > 0 And n2 = 0                      '有 "(" 没 ")"                MsgBox "表达式错误"                Exit Function            Case n2 > 0 And n1 = 0                      '有 ") 没 "("                MsgBox "表达式错误"                Exit Function            Case n1 > n2                                '出现") ("                MsgBox "表达式错误"                Exit Function            Case Else                Do                 '如果出现这种情况"((( )))",则取最里面的括号开始分解                    zl = n1                    n1 = InStr(n1 + 1, a, "(")                Loop Until n1 > n2 Or n1 = 0                th = Mid(a, zl, n2 - zl + 1)                '存放分解出来的式子                th2 = Mid(th, 2, Len(th) - 2)               '去括号                a = Replace(a, th, handle1(th2)) '计算分解出来的式子,并把结果替换进去        End Select    Loop    handle = handle1(a)                         '得到最后结果End FunctionPrivate Function handle1(b)                 '把handle3的每个结果相加    n = handle2(b)    s = 0                                       '累加数初值    For i = 1 To n        s = s + handle3(tt(i))                      '计算各乘除式的值并累加    Next i    handle1 = s                                 '得到结果End Function  Private Function handle2(t)                 '按+,-分解式子    '添以"+"开头,方便处理    If Left(t, 1) <> "+" And Left(t, 1) <> "-" Then t = "+" & t    k = 0                                      '用已累计分解出来的式子数    Do While t <> ""        n1 = InStr(2, t, "+")                       '查找        n2 = InStr(2, t, "-")        k = k + 1        Select Case True            Case n1 = 0 And n2 = 0                      '无+、-号                tt(k) = t                                   '取剩余部分                t = ""            Case n2 = 0 Or (n1 < n2 And n1 > 0)         '无-号或先遇到+号                tt(k) = Left(t, n1 - 1)                     '从该+号开始截取                t = Mid(t, n1)            Case n1 = 0 Or (n1 > n2 And n2 > 0)         '无+号或先遇到-号                tt(k) = Left(t, n2 - 1)                     '从该-号开始截取                t = Mid(t, n2)        End Select    Loop    handle2 = k                                 '分解出来的式子个数End FunctionPrivate Function handle3(x)              '计算handle2分解出来的式子    f = Left(x, 1)                              '取出符号+或-    x = "*" & Mid(x, 2)                         '添以"*"开头,方便处理    Sum = 1                                     '累乘/除的初值    Do While x <> ""        n1 = InStr(2, x, "*")                       '从第2个字符开始查找        n2 = InStr(2, x, "/")        Select Case True            Case n1 = 0 And n2 = 0                      '无乘除号                y = x                x = ""            Case n2 = 0 Or (n1 < n2 And n1 > 0)         '无/号或先遇到*号                y = Left(x, n1 - 1)                         '取至*号前                x = Mid(x, n1)            Case n1 = 0 Or (n1 > n2 And n2 > 0)         '无*号或先遇到/号                y = Left(x, n2 - 1)                         '取至/号前                x = Mid(x, n2)        End Select        If Left(y, 1) = "*" Then                 '根据式子前面的符号进行运算            Sum = Sum * Val(Mid(y, 2))        Else            Sum = Sum / Val(Mid(y, 2))        End If    Loop    handle3 = Val(f & Str(Sum))                 '加上正负号End Function 


[解决办法]

楼主需要的仅仅是字符串替换。核心问题是子串的冲突问题。解决之道就是先替换长串。

只要将字符串提取出来,按长度排序,然后逐个用 Repalce 替换即可。

如果如楼主贴中所示,字母最大不超过 F,且不必区分大小写,则还有更有趣的算法。

窗体上放一个 Sorted = True, Visible = False 的 ListBox 用来排序。(也可用其他排序算法)

Dim strSource As String
Dim strResult As String
Dim strTemp As String
Dim strArray() As String
Dim strList(1, 2) As String
Dim i, j As Integer

strSource = "(A1+D3)*A11"
strList(0, 0) = "A1"
strList(1, 0) = "Var1"
strList(0, 1) = "D3"
strList(1, 1) = "Var2"
strList(0, 2) = "A11"
strList(1, 2) = "Var3"

strTemp = Replace(strSource, "(", "")
strTemp = Replace(strSource, "(", "")
strTemp = Replace(strTemp, ")", "")
strTemp = Replace(strTemp, ")", "")
strTemp = Replace(strTemp, "*", "+")
strTemp = Replace(strTemp, "-", "+")
strTemp = Replace(strTemp, "/", "+")

strArray = Split(strTemp, "+")

List1.Clear
For i = LBound(strArray) To UBound(strArray)
strTemp = "&H" & strArray(i)
If IsNumeric(strTemp) Then List1.AddItem Val(strTemp)
Next i

strResult = strSource
For i = List1.ListCount - 1 To 0 Step -1
strTemp = Hex(List1.List(i))
For j = 0 To UBound(strList, 2)
If strTemp = strList(0, j) Then
strResult = Replace(strResult, strTemp, strList(1, j))
Exit For
End If
Next j
Next i

Debug.Print strResult

注意,你的字符串中有全角字符,需要特别处理。

热点排行