|
本帖最后由 香川群子 于 2014-4-3 14:44 编辑
我的第3种算法代码:
- Sub test3() '测试并输出
- Dim x&, y&
- x = [x1]: y = [y1] '工作表单元格参数赋值
- 'x = 5: y = 8 '或直接赋值测试
- [a1].Resize(x * 2 + 2, y + 2) = 1: [a1].CurrentRegion = "" '清空数据区域
- [a1].Resize(x, y) = luoxuan(x, y) '输出顺时针螺旋矩阵
- [a1].Offset(x + 2).Resize(x, y) = luoxuan(x, y, 1) '输出逆时针螺旋矩阵
- End Sub
- Function luoxuan(ByVal x&, ByVal y&, Optional z& = 0)
- Dim i&, j&, n&, r1&, c1&, k1&, r2&, c2&, k2&
- If z Then n = x: x = y: y = n '如果是逆时针要求 则x、y交换
- ReDim a&(1 To x, 1 To y)
- If x < y Then n = x Else n = y '确定层数n为x、y中的最小值
- r1 = 1: c1 = 1: k1 = 1 '左上角起点行r1、列c1位置以及写入序号k1的初始化
- r2 = x: c2 = y: k2 = k1 + x + y - 2 '右下角起点行r2、列c2位置以及写入序号k2的初始化
- For i = 2 To n Step 2 '层数按步长2循环 (每循环一层能去掉2行 或2列)
- For j = 0 To c2 - c1 - 1 '上行r1和下行r2 按列数差c2-c1循环
- a(r1, c1 + j) = k1 + j '上行r1逐列递增c1+j 写入k1+j
- a(r2, c2 - j) = k2 + j '下行r2逐列递减c2-j 写入k2+j
- Next
- k1 = k1 + j: k2 = k2 + j '更新当前的k1 和 k2值
- For j = 0 To r2 - r1 - 1 '右列c2和左列c1 按行数差r2-r1循环
- a(r1 + j, c2) = k1 + j '右列c2逐行递增r1+j 写入k1+j (注意此时k1已经更新)
- a(r2 - j, c1) = k2 + j '左列c1逐行递减r2-j 写入k2+j (注意此时k2已经更新)
- Next
- k1 = k2 + j '更新下一层的左上起点k1值 (最后的左列值+1)
- k2 = k1 + (x - 1 - i) + (y - 1 - i) '更新下一层的右下起点k2值 (按新的k1值计算 并加上x、y方向增量)
- r1 = r1 + 1: c1 = c1 + 1 '更新左上起点位置r1、c1
- r2 = r2 - 1: c2 = c2 - 1 '更新右下起点位置r2、c2
- Next
- '上述整数层循环写入完成后 如果是奇数则还剩一行或一列待填写
- If n Mod 2 Then '判断是否奇数层
- If x < y Then '如果行x小于列y
- For j = 0 To c2 - c1 '则新的r1行循环各列
- a(r1, c1 + j) = k1 + j
- Next
- Else '行x大于或等于列y时
- For j = 0 To r2 - r1'则新的c2列循环各行
- a(r1 + j, c2) = k1 + j
- Next
- End If
- End If
-
- If z Then luoxuan = Application.Transpose(a) Else luoxuan = a
- '如果要求逆时针则需要对结果数组进行 行列转置
- End Function
复制代码 呵呵,简单明了。
|
评分
-
1
查看全部评分
-
|