ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
123
返回列表 发新帖

[讨论] VBA通过二个题目加深对数组赋值的理解-----蛇形矩阵和螺旋矩阵,详情见附件

[复制链接]

TA的精华主题

TA的得分主题

发表于 2014-3-31 15:16 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖已被收录到知识树中,索引项:数组集合和字典
本帖最后由 香川群子 于 2014-3-31 16:18 编辑

顺时针或逆时针螺旋

  1. Sub test2() 'by kagawa 顺时针或逆时针螺旋
  2.     Dim i&, ii&, j&, jj&, k&, l&, ll&, n&, t&, tt&, x&, y&, z&
  3.    
  4.     [a1].CurrentRegion = ""
  5.     x = InputBox("行数x=", , Int(Rnd * 50 + 5))
  6.     y = InputBox("列数y=", , Int(Rnd * 25 + 3))
  7.     z = MsgBox("螺旋方向z=: Yes 顺时针 / No 逆时针", vbYesNo)
  8.     ReDim a(1 To x, 1 To y)
  9.    
  10.     If z = vbYes Then
  11.         i = 1: j = 0: If y < x Then n = y * 2 - 1 Else n = x * 2 - 2
  12.     Else
  13.         i = 0: j = 1: If x < y Then n = x * 2 - 1 Else n = y * 2 - 2
  14.     End If
  15.     '以上计算最大折曲次数 (直线次数-1)
  16.     r = Array(0, 1, 0, -1) '折曲时行、列增量的变化规律
  17.    
  18.     For t = 0 To n '遍历每一次直线过程
  19.         tt = (t + 1) \ 2 '本次总长度减量
  20.         If z = vbYes Then
  21.             ii = r(t Mod 4): jj = r((t + 1) Mod 4)
  22.             ll = IIf(t Mod 2, x - tt, y - tt)
  23.         Else
  24.             ii = r((t + 1) Mod 4): jj = r(t Mod 4)
  25.             ll = IIf(t Mod 2, y - tt, x - tt)
  26.         End If
  27.         '以上计算每一直线状态的行增量、列增量 以及有效长度

  28.         For l = 1 To ll '按有效长度递增
  29.             i = i + ii: j = j + jj
  30.             k = k + 1: a(i, j) = k
  31.             [a1].Resize(x, y) = a '直接观察 输出结果到工作表 (要速度时这句注释掉)
  32.         Next
  33.     Next

  34.     Application.StatusBar = x & " x " & y & " = " & x * y
  35.     [a1].Resize(x, y) = a '输出结果到工作表
  36.     [a1].Cells(i, j).Activate '光标停留到中央最后位置
  37. End Sub
复制代码

点评

z = MsgBox("z=", vbYesNo)  发表于 2014-3-31 15:55
z = MsgBox("z=", vbYesNo)  发表于 2014-3-31 15:55

TA的精华主题

TA的得分主题

发表于 2014-3-31 16:48 | 显示全部楼层
本帖最后由 香川群子 于 2014-3-31 17:13 编辑
浮华、缠绕指尖 发表于 2014-3-31 14:27
嗯,其实整体思路是没变的,你的代码的亮点在于辅助数组r=Array(0,1,0,-1),这个用得是非常好,代替了他们 ...


速度比较:

x= 50 y= 50
Run Count: 10,000
Test1: 4.2656s   我的Do循环
Test2: 3.1055s   我的直接增量计算
Test3: 6.8008s   lsdongjh的Do循环
Test4: 3.6563s   16楼[141475046]的四角推进算法
--End--


我的代码中
r = Array(0, 1, 0, -1)  
改成
Dim r&(3): r(1) = 1: r(3) = -1

速度能稍快一些


…………
16楼[141475046]的四角推进算法,也很有意思,尤其是顺时针、逆时针的转换毫不费力。
但缺点是:只能做正方形矩阵,暂时还无法处理长方形矩阵。(需要边长不等的计算和处理)


TA的精华主题

TA的得分主题

发表于 2014-4-1 00:13 | 显示全部楼层
四角推进法的长方矩形代码:

暂时只做了顺时针的。
  1. Sub test() 循环演示
  2.     Dim i&, j&
  3.     For i = 1 To 12
  4.         For j = 1 To 12
  5.             Call test4(i, j)
  6.         Next
  7.     Next
  8. End Sub

  9. Sub test4(x&, y&) '代码过程
  10.     Dim i&, ii&, j&, jj&, k&, l&, ll&, n&, t&, tt& ', x&, y&, z&
  11.    
  12.     [a1].CurrentRegion = ""
  13. '    x = InputBox("行数x=", , Int(Rnd * 50 + 5))
  14. '    y = InputBox("列数y=", , Int(Rnd * 25 + 3))
  15. '    z = MsgBox("螺旋方向z=: Yes 顺时针 / No 逆时针", vbYesNo)
  16.    

  17.     ReDim a&(1 To x, 1 To y)
  18.     If x < y Then r = x Else r = y
  19.     r1 = 1: c1 = 1: r2 = x: c2 = y: k1 = 1: k2 = k1 + x + y - 2
  20.     For n = 1 To r - 1 Step 2
  21.         For j = 0 To c2 - c1 - 1
  22.             Cells(r1, c1 + j) = k1 + j
  23.             Cells(r2, c2 - j) = k2 + j
  24.         Next
  25.         k1 = k1 + j: k2 = k2 + j
  26.         For j = 0 To r2 - r1 - 1
  27.             Cells(r1 + j, c2) = k1 + j
  28.             Cells(r2 - j, c1) = k2 + j
  29.         Next
  30.         k1 = k2 + j: k2 = k1 + x + y - n * 2 - 4
  31.         r1 = r1 + 1: c1 = c1 + 1: r2 = r2 - 1: c2 = c2 - 1
  32.     Next
  33.     If c1 > 1 Then Cells(r2 - j + 2, c1 - 1).Activate
  34.    
  35.     If r Mod 2 Then
  36.         If x < y Then
  37.             For j = 0 To c2 - c1
  38.                 Cells(r1, c1 + j) = k1 + j
  39.             Next
  40.             Cells(r1, c1 + j - 1).Activate
  41.         Else
  42.             For j = 0 To r2 - r1
  43.                 Cells(r1 + j, c2) = k1 + j
  44.             Next
  45.             Cells(r1 + j - 1, c2).Activate
  46.         End If
  47.     End If
  48. End Sub
复制代码
如改成存入数组,则运算速度快。

TA的精华主题

TA的得分主题

 楼主| 发表于 2014-4-1 08:12 | 显示全部楼层
香川群子 发表于 2014-4-1 00:13
四角推进法的长方矩形代码:

暂时只做了顺时针的。如改成存入数组,则运算速度快。

非常感谢裙子,有心了

TA的精华主题

TA的得分主题

发表于 2014-4-1 10:51 | 显示全部楼层
顺时针和逆时针,只要通过转置就可以了。
  1. Sub test44()
  2.     Dim i&, j&, k1&, k2&, r1&, c1&, r2&, c2&, r&, n&, x&, y&, z&
  3.    
  4.     [a1].CurrentRegion = ""
  5.     x = InputBox("行数x=", , Int(Rnd * 50 + 5))
  6.     y = InputBox("列数y=", , Int(Rnd * 25 + 3))
  7.     z = MsgBox("螺旋方向z=: Yes ??? / No 逆??", vbYesNo)
  8.     If z = vbNo Then r = x: x = y: y = r

  9.     ReDim a&(1 To x, 1 To y)
  10.     If x < y Then r = x Else r = y
  11.     r1 = 1: c1 = 1: r2 = x: c2 = y: k1 = 1: k2 = k1 + x + y - 2
  12.     For n = 1 To r - 1 Step 2
  13.         For j = 0 To c2 - c1 - 1
  14.             a(r1, c1 + j) = k1 + j
  15.             a(r2, c2 - j) = k2 + j
  16.         Next
  17.         k1 = k1 + j: k2 = k2 + j
  18.         For j = 0 To r2 - r1 - 1
  19.             a(r1 + j, c2) = k1 + j
  20.             a(r2 - j, c1) = k2 + j
  21.         Next
  22.         k1 = k2 + j: k2 = k1 + x + y - n * 2 - 4
  23.         r1 = r1 + 1: c1 = c1 + 1: r2 = r2 - 1: c2 = c2 - 1
  24.     Next
  25.     If c1 > 1 Then If z = vbYes Then Cells(r2 - j + 2, c1 - 1).Activate Else Cells(c1 - 1, r2 - j + 2).Activate
  26.    
  27.     If r Mod 2 Then
  28.         If x < y Then
  29.             For j = 0 To c2 - c1
  30.                 a(r1, c1 + j) = k1 + j
  31.             Next
  32.             If z = vbYes Then Cells(r1, c1 + j - 1).Activate Else Cells(c1 + j - 1, r1).Activate
  33.         Else
  34.             For j = 0 To r2 - r1
  35.                 a(r1 + j, c2) = k1 + j
  36.             Next
  37.             If z = vbYes Then Cells(r1 + j - 1, c2).Activate Else Cells(c2, r1 + j - 1).Activate
  38.         End If
  39.     End If
  40.     Application.StatusBar = x & " x " & y & " = " & x * y
  41.     If z = vbYes Then [a1].Resize(x, y) = a Else [a1].Resize(y, x) = Application.Transpose(a)
  42. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2014-4-3 11:28 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
yjh_27 也写了代码,链接在这里
http://club.excelhome.net/forum. ... id=1109068#lastpost

TA的精华主题

TA的得分主题

发表于 2015-1-23 09:51 | 显示全部楼层
不錯,代碼簡潔,運行正確 ,學習

TA的精华主题

TA的得分主题

发表于 2017-3-10 21:43 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-8 10:27 , Processed in 0.047733 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表