|
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
与去重相关的代码:
- Public Sub quchong() '去重
- If cx <> 1 Then MsgBox "请先进行快速筛选!", , "友情提示": Exit Sub
- Dim h%, i%, j%, i1%, j1%, k%, l%, n%, m%, zhs%, s, s1$, arr, brr, qp1, bhjd%, bhlx%, x% '对应序号与坐标
- Range("p2:q" & Rows.Count).ClearContents
- n = 8 '皇后数
- ReDim xh(1 To n ^ 2, 1 To 2), qp(1 To n, 1 To n)
- m = 0
- For i1 = 1 To n
- For j1 = 1 To n
- m = m + 1
- xh(m, 1) = i1: xh(m, 2) = j1 '记录值的坐标
- Next j1
- Next i1
- arr = Range("k2:k" & Range("k2").End(xlDown).Row).Value
- zhs = UBound(arr) '组合数
- For i = 1 To zhs - 1
- If arr(i, 1) <> "" Then
- s = Split(arr(i, 1), ",")
- For i1 = 1 To n
- For j1 = 1 To n
- qp(i1, j1) = 0 '棋盘初始化,必须初始化为0,不能为"",否则变换函数返回值会出错
- Next j1
- Next i1
- For j = LBound(s) To UBound(s)
- qp(xh(s(j), 1), xh(s(j), 2)) = s(j) '这个嵌套的费事:棋盘落子情况
- Next j
- For l = 1 To 7 '每种棋盘状况经历7种变换
- bhjd = Choose(l, 90, 180, 270, 45, 90, 135, 180) '变换角度
- If l < 4 Then bhlx = 1 Else bhlx = 2 '变换类型
- qp1 = BianHuan(qp, bhjd, bhlx) '变换棋盘
- m = 0: s1 = ""
- For j = 1 To n
- For k = 1 To n
- m = m + 1
- If qp1(j, k) <> 0 Then qp1(j, k) = m: s1 = s1 & qp1(j, k) & "," '调整棋子序号,连接变换后的字符串
- Next k
- Next j
- s1 = Left(s1, Len(s1) - 1)
- For h = i + 1 To zhs '剔除重复组合
- If arr(h, 1) = s1 Then arr(h, 1) = "": x = x + 1: Exit For
- Next h
- Next l
- End If
- Next i
- ReDim brr(1 To zhs - x, 1)
- m = 0
- For i = 1 To zhs
- If arr(i, 1) <> "" Then m = m + 1: brr(m, 0) = m: brr(m, 1) = arr(i, 1)
- Next i
- Range("p2").Resize(UBound(brr) - LBound(brr) + 1, UBound(brr, 2) - LBound(brr, 2) + 1) = brr
- cx = 0
- Dim xz%, zhd% '选择、中断
- xz = MsgBox("是否进行直观演示?", vbYesNo, "友情提示")
- If xz = vbNo Then Exit Sub
- zhd = 0
- For i = 1 To zhs - x
- Range(Cells(1, 1), Cells(8, 8)).ClearContents
- s = Split(brr(i, 1), ",")
- For j = LBound(s) To UBound(s)
- Cells(xh(s(j), 1), xh(s(j), 2)).Value = "●"
- Next j
- If zhd = 0 Then
- xz = MsgBox("这是第" & brr(i, 0) & "种结果" & Chr(10) & "是否继续分步演示?", vbYesNo, "友情提示")
- If xz = vbNo Then zhd = 1
- End If
- Next i
- End Sub
复制代码
下面是上段代码调用的变换自定义函数,改成了数组形式(想来您指导过既可以使用单元格区域的,也可以使用内存数组的,后面一并研究):
- Public Function BianHuan(rng, jd%, Optional n% = 1) '旋转和对称变换自定义函数
- Dim arr, h%, l%, i%, j%, hl%, x!, y!, hd#, h1%, l1%, m%, k%
- arr = rng '原始数据数组
- h = UBound(arr): l = UBound(arr, 2)
- If n = 1 Then
- If jd = 90 Then jd = 270 Else If jd = 270 Then jd = 90 '工作表其实是第四象限,相当于转为第一象限
- ElseIf n = 2 Then
- If jd = 45 Then jd = 135 Else If jd = 135 Then jd = 45 '工作表其实是第四象限,相当于转为第一象限
- End If
- hl = WorksheetFunction.Max(h, l): hd = jd / 180 * Application.Pi()
- ReDim brr(-hl To hl, -hl To hl) '过渡数组
- For i = 1 To h '对应y
- For j = 1 To l '对应x
- If n = 1 Then
- x = j * Cos(hd) - i * Sin(hd)
- y = j * Sin(hd) + i * Cos(hd)
- brr(y, x) = arr(i, j)
- ElseIf n = 2 Then
- x = j * Cos(hd * 2) + i * Sin(hd * 2)
- y = j * Sin(hd * 2) - i * Cos(hd * 2)
- brr(y, x) = arr(i, j)
- End If
- Next j
- Next i
- h1 = 0: l1 = 0
- For i = -hl To hl '非空列
- m = 0
- For j = -hl To hl
- If brr(i, j) <> "" Then m = m + 1
- Next j
- If l1 < m Then l1 = m
- Next i
- If l1 = l Then h1 = h Else h1 = l '非空行
- ReDim crr(1 To h1, 1 To l1)
- m = 0: k = 1
- For i = -hl To hl '剔除brr中的空值,保留非空值位置
- For j = -hl To hl
- If brr(i, j) <> "" Then m = m + 1: crr(k, m) = brr(i, j)
- Next j
- If m <> 0 Then k = k + 1
- m = 0
- Next i
- BianHuan = crr
- End Function
复制代码
|
|