本帖最后由 lee1892 于 2013-1-18 14:10 编辑
不知道我理解正确不:
代码: | Sub Calculation()
Dim t#, aData, aResult(), aOutput(), aCount&(), nInitial&
Dim i&, j&, k&, i1st%, i2nd%, i3rd%, i4th%, sIndex, aInds
Dim dCode As Object, aCodes, aIndexes, nDiff&, nNew&, nSmall&
t = Timer
On Error GoTo CLEAR_BUFFER
' ===========================================
' 输入
aData = Sheet2.Cells(1, 1).CurrentRegion
' ===========================================
Set dCode = CreateObject("Scripting.Dictionary")
ReDim aCount(0 To 25, 0 To 25, 0 To 25, 0 To 25)
For i = 1 To UBound(aData)
i1st = Asc(Mid(aData(i, 3), 1, 1)) - 97
i2nd = Asc(Mid(aData(i, 3), 2, 1)) - 97
i3rd = Asc(Mid(aData(i, 3), 3, 1)) - 97
i4th = Asc(Mid(aData(i, 3), 4, 1)) - 97
sIndex = Join(Array(i1st, i2nd, i3rd, i4th), ",")
aCount(i1st, i2nd, i3rd, i4th) = aCount(i1st, i2nd, i3rd, i4th) + 1
If aCount(i1st, i2nd, i3rd, i4th) = 2 Then
nInitial = nInitial + 2
ElseIf aCount(i1st, i2nd, i3rd, i4th) > 2 Then
nInitial = nInitial + 1
End If
If Not dCode.exists(aData(i, 1)) Then
Set dCode(aData(i, 1)) = CreateObject("Scripting.Dictionary")
dCode(aData(i, 1))("LETTER") = i3rd
End If
If Not dCode.exists(aData(i, 2)) Then
Set dCode(aData(i, 2)) = CreateObject("Scripting.Dictionary")
dCode(aData(i, 2))("LETTER") = i4th
End If
dCode(aData(i, 1))(sIndex) = dCode(aData(i, 1))(sIndex) + 1
If aData(i, 1) <> aData(i, 2) Then 'If i3rd <> i4th Then 此处有误!不应比较第3列的最后两个字母,而应比较1、2列
dCode(aData(i, 2))(sIndex) = dCode(aData(i, 2))(sIndex) + 1
End If
Next
ReDim aResult(0 To dCode.Count, 1 To 26)
For i = 1 To 26
aResult(0, i) = Chr(i + 96)
Next
ReDim aOutput(1 To dCode.Count, 1 To 2)
aCodes = dCode.keys
For i = 0 To UBound(aCodes)
i1st = dCode(aCodes(i))("LETTER")
aOutput(i + 1, 1) = aCodes(i) & ":" & Chr(i1st + 97)
nSmall = nInitial
For j = 0 To 25
nDiff = 0
If j = i1st Then GoTo NEXT_LETTER
For Each sIndex In dCode(aCodes(i)).keys
If sIndex = "LETTER" Then GoTo JUMP_FIRST
aInds = Split(sIndex, ",")
i3rd = aInds(2): i4th = aInds(3)
If i3rd = i1st Then i3rd = j
If i4th = i1st Then i4th = j
If aCount(aInds(0), aInds(1), i3rd, i4th) > 1 Then
nDiff = nDiff - aCount(aInds(0), aInds(1), i3rd, i4th)
End If
If aCount(aInds(0), aInds(1), aInds(2), aInds(3)) > 1 Then
nDiff = nDiff - aCount(aInds(0), aInds(1), aInds(2), aInds(3))
End If
nNew = aCount(aInds(0), aInds(1), i3rd, i4th) + dCode(aCodes(i))(sIndex)
If nNew > 1 Then
nDiff = nDiff + nNew
End If
nNew = aCount(aInds(0), aInds(1), aInds(2), aInds(3)) - dCode(aCodes(i))(sIndex)
If nNew > 1 Then
nDiff = nDiff + nNew
End If
JUMP_FIRST: Next
NEXT_LETTER:
aResult(i + 1, j + 1) = nInitial + nDiff
If aResult(i + 1, j + 1) < nSmall Then
nSmall = aResult(i + 1, j + 1)
aOutput(i + 1, 2) = Chr(j + 97) & ":" & nSmall
ElseIf aResult(i + 1, j + 1) = nSmall Then
aOutput(i + 1, 2) = aOutput(i + 1, 2) & "," & Chr(j + 97) & ":" & nSmall
End If
Next
If Left(aOutput(i + 1, 2), 1) = "," Then
aOutput(i + 1, 2) = Right(aOutput(i + 1, 2), Len(aOutput(i + 1, 2)) - 1)
End If
Next
' ===========================================
' 输出
With Sheet1
.Cells.ClearContents
.Cells(2, 1).Resize(UBound(aOutput, 1), UBound(aOutput, 2)) = aOutput
.Cells(1, 3).Resize(UBound(aResult, 1) + 1, UBound(aResult, 2)) = aResult
End With
' ===========================================
CLEAR_BUFFER:
For i = 0 To UBound(aCodes)
dCode(aCodes(i)).RemoveAll
Set dCode(aCodes(i)) = Nothing
Next
dCode.RemoveAll: Set dCode = Nothing
Debug.Print Timer - t
End Sub
|
|