|
|
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
本帖最后由 香川群子 于 2011-10-15 00:44 编辑
winland 发表于 2006-12-25 12:41 
我把我的递归方法改了一下, 用上了数组, 速度也快了很多, 23个1大概两到三秒.
我自己写的递归迭代方法,23个1 ,光计算是0.6秒,连写入单元格是2.8秒。而楼主最快的第6稿代码在我的机子上是8.14秒。
因此,显然比楼主的代码快多了。
- Public brr(), k As Long
- Sub codecombin()
- [c2] = Timer
- Randomize
- [a:b].Clear
-
- s = Int(10 ^ (Rnd() * 10))
- Do
- l = InStr(s, 0)
- If l = 0 Then Exit Do
- t = Mid(s, l - 1, 1)
- If t > "2" Or t = " " Then
- s = Left(s, l - 1) & Mid(s, l + 1)
- Else
- s = Left(s, l - 1) & "o" & Mid(s, l + 1)
- End If
- Loop
- s = Replace(s, "o", 0)
- '以上为得到随机数值,并检查、去掉不合理和多余的0
-
- ' s = String(23, "1") '最大23个重复1的检测
- ' s = "6" '调试bug
-
- [a1] = "' " & s
- [c1] = Timer
-
- If Len(s) = 1 Then
- s = Chr(64 + Val(s))
- [a2] = s
- [b2] = CodeChk(s)
- [c1] = Timer - [c1]
- [c2] = Timer - [c2]
- Exit Sub
- End If
- '以上为一位数值时直接转换为字母并结束。
-
- s = " " & s & " "
- l = Len(s)
-
- t = Left(s, 1)
- For i = 2 To l - 2
- t0 = t
- t = Mid(s, i, 1)
- If t = "0" Then
- s = Left(s, i - 2) & " " & Chr(64 + Val(Mid(s, i - 1, 2))) & Right(s, l - i)
- ElseIf t = "1" Then
- If t0 = " " Or t0 = "0" Or t0 > "2" Then
- If Mid(s, i + 2, 1) = "0" Or Mid(s, i + 1, 2) = " " Then
- s = Left(s, i - 1) & "A" & Right(s, l - i)
- ' s = Left(s, i - 1) & Chr(64 + Val(t)) & Right(s, l - i)
- End If
- End If
- ElseIf t = "2" Then
- If t0 = " " Or t0 = "0" Or t0 > "2" Then
- If Mid(s, i + 1, 1) > "6" Or Mid(s, i + 2, 1) = "0" Or Mid(s, i + 1, 2) = " " Then
- s = Left(s, i - 1) & "B" & Right(s, l - i)
- ' s = Left(s, i - 1) & Chr(64 + Val(t)) & Right(s, l - i)
- End If
- End If
- ElseIf t > "2" Then
- If t0 = " " Or t0 = "0" Or t0 > "2" Or (t0 = "2" And t > "6") Then
- s = Left(s, i - 1) & Chr(64 + Val(t)) & Right(s, l - i)
- End If
- End If
- Next
- '以上为检查各数值,如无分歧则直接转换为字母。
-
- s = Replace(Mid(s, 2), " ", "")
- [a2] = s
-
- n1 = InStr(s, 1): n2 = InStr(s, 2)
- If n1 * n2 Then
- If n1 < n2 Then t = n1 Else t = n2
- Else
- t = n1 + n2
- End If
- '以上为检查转换结果中是否还含有数字1或2。
-
- If t = 0 Then
- [b2] = CodeChk(s)
- [c1] = Timer - [c1]
- [c2] = Timer - [c2]
- Exit Sub
- End If
- '以上为,检查结果中已经不含1或2时,肯定没有分歧了,可以直接输出转换字母结果。
-
- k = 0
- ReDim brr(1 To 65536, 1 To 2)
-
- dg s, t
- '开始递归过程……
- [c1] = Timer - [c1]
- '递归结束,已经得到储存在数组brr中的最终结果。
-
- s = "'" & [a1]
- For i = 1 To k
- brr(i, 2) = CodeChk(brr(i, 1))
- If brr(i, 2) <> s Then
- MsgBox "Err"
- End If
- Next
- '以上为对转换字母结果逐一确认,再转换为数值时是否相同。
-
- [a2].Resize(k, 2) = brr 'WorksheetFunction.Transpose(brr)
- [c2] = Timer - [c2]
- '以上为把数组brr中的最终结果输出到工作表,结束。
-
- End Sub
- Sub dg(A, n)
- b = Mid(A, n, 1)
- If IsNumeric(b) Then
- If b > "2" Then
- A = Left(A, n - 1) & Chr(64 + Val(b)) & Right(A, Len(A) - n)
- ' ElseIf b = "0" Then
- ' A = Left(A, n - 1) & Right(A, Len(A) - n)
- Else
- a1 = Left(A, n - 1) & Chr(64 + Val(b)) & Right(A, Len(A) - n)
- If n < Len(a1) Then
- dg a1, n + 1
- Else
- k = k + 1
- brr(k, 1) = a1
- Exit Sub
- End If
-
- If IsNumeric(Mid(A, n + 1, 1)) Then
- a2 = Left(A, n - 1) & Chr(64 + Val(Mid(A, n, 2))) & Right(A, Len(A) - n - 1)
- For i = n + 1 To Len(a2)
- If IsNumeric(Mid(a2, i, 1)) Then
- dg a2, i
- Exit Sub
- End If
- Next
- k = k + 1
- brr(k, 1) = a2
- End If
-
- Exit Sub
- End If
- End If
- n1 = InStr(A, 1): n2 = InStr(A, 2)
- If n1 * n2 Then
- If n1 < n2 Then t = n1 Else t = n2
- Else
- t = n1 + n2
- If t = 0 Then
- k = k + 1
- brr(k, 1) = A
- Exit Sub
- End If
- End If
- dg A, t
-
- End Sub
- Function CodeChk(A)
- t = "' "
- For i = 1 To Len(A)
- t = t & Asc(Mid(A, i, 1)) - 64
- Next
- CodeChk = t
- End Function
复制代码 |
|