|
本帖最后由 香川群子 于 2013-6-14 21:01 编辑
代码加了必要的注释:
- Sub RndTest()
- l = Len([a1]) '获取数位长度
- [a1] = f(l) 'A1中写入起始状态 (随机生成)
- [b1] = f(l) 'B1中写入结果状态 (随机生成)
- kagawa '调用计算主过程
- End Sub
- Sub kagawa()
- tms = Timer
- ' s = "111111111": t = "000000000" '=2^8=256
- ' s = "000000000": t = "111111111" '=2^8=256
- ' s = "000000001": t = "000000000" '=2^7-1+2^8=383
-
- s = [a1]: l = Len(s): ReDim jg$(2 ^ l + 2): jg(0) = s
- '以下为对s进行预处理到达 "00xxxxxxx" 的理想初始状态
- If Left(s, 2) = "00" Then k = 1
- If Left(s, 1) = "1" Then Mid(s, 1, 2) = "00": jg(1) = s: k = 2
- If Left(s, 2) = "01" Then Mid(s, 1, 2) = "11": jg(1) = s: Mid(s, 1, 2) = "00": jg(2) = s: k = 3
-
- t = [b1]: If Left(t, 2) = "10" Then Mid(t, 1, 2) = "00" '对结果t进行预处理,排除讨厌的"10xxxxxxx"
-
- ' [d8].CurrentRegion.Offset(1) = "": [d9] = 9: [e9] = "'" & s
- For i = l To 3 Step -1 '倒序检查s和t对应每个位置是否状态相同
- Do Until Mid(s, i, 1) = Mid(t, i, 1) 'Do循环直到状态相同 (0对0 或 1对1)
- Call dg(i) '如果状态不同则进行 递归【反位】(0-1互换)
- ' [d65536].End(3).Offset(1) = i
- ' [e65536].End(3).Offset(1) = "'" & s
- Loop
- Next
- '以上循环结束时,从第3位开始的状态已经递归反位处理结束达到s和t的相同状态。
-
- '以下为对最先2位进行标准化处理 并找到准确的结果位置k 解释略
- If Left([b1], 2) = "10" Then
- For k = IIf(k > 6, k - 6, 0) To k - 1
- If jg(k) = t Then Exit For
- Next
- s = jg(k): k = k + 1: Mid(s, 1, 2) = "10": jg(k) = s
- Else
- If Left(s, 2) = "11" Then Mid(s, 1, 2) = "00": jg(k) = s: k = k + 1
- Mid(s, 1, 2) = "11": jg(k) = s: k = k + 1
- Mid(s, 1, 2) = "01": jg(k) = s: k = k + 1
- For k = IIf(k > 8, k - 8, 0) To k - 1
- If jg(k) = t Then Exit For
- Next
- End If
-
- '输出结果到工作表
- [a2:a65536].Clear: [a2].Resize(k).NumberFormat = "@"
- [a1].Resize(k + 1) = Application.Transpose(jg)
-
- '以下为排除起始状态的可能的重复
- For i = 1 To 2
- If jg(i) = jg(0) Then
- [a1].Resize(k + 1).Value = [a1].Offset(i).Resize(k + 1).Value
- k = k - i
- End If
- Next
-
- '到达结果位置
- [a1].Offset(k).Activate
- Erase jg
- MsgBox Format(Timer - tms, "0.000s ") & k
- End Sub
- Sub dg(n) '对第n个位置进行【0-1互换】 的递归过程 也即对第n位状态进行【反位】处理
- If n = 3 Then '递归到只剩前3位时就可以按照规律进行:上12下1、3【反位】、上1下12、最先一个"1"之后【反位】
- Mid(s, 1, 2) = "11": jg(k) = s: k = k + 1 '上12
- Mid(s, 1, 2) = "01": jg(k) = s: k = k + 1 '下1
- Mid(s, 3, 1) = IIf(Mid(s, 3, 1) = "1", "0", "1"): jg(k) = s: k = k + 1 '3【反位】(0-1互换)
- Mid(s, 1, 2) = "11": jg(k) = s: k = k + 1 '上1
- Mid(s, 1, 2) = "00": jg(k) = s: k = k + 1 '下12
- For i = 3 To l - 1 '查找第1个出现"1"的位置 即 00001x*** 类型
- If Mid(s, i, 1) = "1" Then '"0"之后第1个"1"的下一个x进行【反位】(0-1互换)
- Mid(s, i + 1, 1) = IIf(Mid(s, i + 1, 1) = "1", "0", "1"): jg(k) = s: k = k + 1
- Exit For '退出
- End If
- Next
- Else
- If Mid(s, n - 1, 1) = "1" Then '检查n-1位置必须是"1" 即 xxxx1**** 类型
- For i = n - 2 To 3 Step -1 '继续检查n-2位置(必须是"0")
- If Mid(s, i, 1) = "1" Then Call dg(i) '如果是"1"则递归【反位】
- Next
-
- If k > 1 Then '因为要检查k-1以及k-2的s状态到n-1位置是否不同所以必须k>1
- If Left(s, n - 2) = String(n - 2, "0") Then '首先检查到n-2位置是否都是"0" 即 00001x*** 类型
- If Left(jg(k - 1), n - 1) <> Left(jg(k - 2), n - 1) Then
- '再检查k-1以及k-2的s状态到第n-1位置是否相同 如不同则可以【反位】(0-1互换)
- Mid(s, n, 1) = IIf(Mid(s, n, 1) = "1", "0", "1"): jg(k) = s: k = k + 1
- Else '如相同则不需要【反位】(将退回前一状态)
- ' Stop
- End If
- End If
- Else 'k=1 时可直接对第n位置进行【反位】(0-1互换)
- Mid(s, n, 1) = IIf(Mid(s, n, 1) = "1", "0", "1"): jg(k) = s: k = k + 1
- End If
- Else '如果检查n-1位置不是"1"而是"0",则需要递归【反位】即把"0"转换为"1"
- Call dg(n - 1)
- End If
- End If
- ' [f65536].End(3).Offset(1) = n
- ' [g65536].End(3).Offset(1) = "'" & s
- End Sub
- Function f(n) '按指定位数生成随机0、1状态
- ' Application.Volatile
- Randomize
- For i = 1 To n
- f = f & IIf(Rnd < 0.5, 0, 1)
- Next
- End Function
复制代码 |
|