Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
楼主: haiyang81

[已解决]求数组元素连续个数最大值和最大值个数的代码

  [复制链接]
 楼主| 发表于 2011-11-5 22:44 | 显示全部楼层
若是求arr=array(0,1,1,1,0,0,2,2,1,3,3,0,0,1,1,1,2,3,0,2)最后一个元素的连续最大值及出现连续最大值的次数。该数组中UBound(arr)=2,2出现的连续最大值为2,出现连续最大值的次数为1。结果用数组表示,pd=Array(2,2,1)
若是数组为Arr = Array(0, 1, 1, 1, 0, 0, 2, 2, 1, 3, 3, 0, 0, 1, 1, 1, 2, 3, 0, 2, 0, 0, 0, 0),
该数组中UBound(arr)=0,0出现的连续最大值为4,出现连续最大值的次数为1。结果为pd=Array(0,4,1)
excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
回复

使用道具 举报

 楼主| 发表于 2011-11-5 22:45 | 显示全部楼层
正在看资料馆中正则表达式的讲解,不过不是很明白
回复

使用道具 举报

 楼主| 发表于 2011-11-6 19:23 | 显示全部楼层
本帖最后由 haiyang81 于 2011-11-6 21:32 编辑

回复 爱疯 的帖子

若是求arr=array(0,1,1,1,0,0,2,2,1,3,3,0,0,1,1,1,2,3,0,2)最后一个元素的连续最大值及出现连续最大值的次数。该数组中最后一个元素UBound(arr)=2,2出现的连续最大值为2,出现连续最大值的次数为1。结果用数组表示,pd=Array(2,2,1)
若是数组为Arr = Array(0, 1, 1, 1, 0, 0, 2, 2, 1, 3, 3, 0, 0, 1, 1, 1, 2, 3, 0, 2, 0, 0, 0, 0),
该数组中最后一个元素UBound(arr)=0,0出现的连续最大值为4,出现连续最大值的次数为1。结果为pd=Array(0,4,1)

代码该如何修改。


总算弄明白了点。按上述所说如何修改代码,这个会了。主要是把i=A(Ubound(A)) 即可.

回复

使用道具 举报

发表于 2011-11-6 22:28 | 显示全部楼层
你的意思是不是这样:
pd=Array(被查找值,连续长度,出现次数)

我是没习惯查看和使用,所以建议还是用一维或二维表示。
因为不知你的后面或整体的想法,所以不好回答。
回复

使用道具 举报

发表于 2012-2-10 11:03 | 显示全部楼层
爱疯 发表于 2011-11-4 13:32
这题有代表性,做了还是发这儿吧,以后好COPY

你这个代码有致命缺陷:

A = Array(0, 1, 1, 1, 0, 0, 2, 2, 1, 3, 3, 0, 0, 1, 1, 1, 2, 3, 0, 2, 5)

对于这个数组,统计结果错误之处为:

0 正确
1 正确
2 正确
3 正确
4 错误 (返回了不存在值) 显然是输出结果部分代码有问题。

5 错误 (返回: 最大次数=0,出现次数=0,而正确结果应为: 最大次数=1,出现次数=1

显然,是对最后一个值,没有统计进去。





回复

使用道具 举报

发表于 2012-2-10 11:07 | 显示全部楼层
爱疯 发表于 2011-11-4 19:19
由于1楼条件正巧,造成两个巧合:

1)使得两种题意得到相同结果。所以,有的理解为A,有的理解为B。

呵呵。3楼代码也有同样缺陷……

原来已经被发现了,但是代码没有做修正,为什么?


回复

使用道具 举报

发表于 2012-2-10 11:12 | 显示全部楼层
本帖最后由 香川群子 于 2012-2-10 21:42 编辑

前面所有人的代码,算法都不是很好……

如果【前提是,统计对象为数值0-9】
那这么简单的问题,根本就不需要用到字典。

用纯数组方法可以轻松处理:

  1. Sub ArrayCount()
  2.     Dim i%

  3.     Arr = Array(0, 1, 1, 1, 0, 0, 2, 2, 1, 3, 3, 0, 0, 1, 1, 1, 2, 3, 0, 2, 5)
  4.     ReDim brr(9, 2) '假定目前处理对象为数字0-9
  5.     For i = 0 To UBound(Arr) - 1
  6.         If Arr(i) = Arr(i + 1) Then
  7.             brr(Arr(i), 0) = brr(Arr(i), 0) + 1
  8.         Else
  9.             If brr(Arr(i), 0) > brr(Arr(i), 1) Then
  10.                 brr(Arr(i), 1) = brr(Arr(i), 0)
  11.                 brr(Arr(i), 2) = 1
  12.             ElseIf brr(Arr(i), 0) = brr(Arr(i), 1) Then
  13.                 brr(Arr(i), 2) = brr(Arr(i), 2) + 1
  14.             End If
  15.             brr(Arr(i), 0) = 0
  16.         End If
  17.     Next
  18.     '循环0-ubound()-1完成以后,接下来对最后一个值也要判断处理
  19.         If Arr(i) = Arr(i - 1) Then
  20.             If brr(Arr(i), 0) > brr(Arr(i), 1) Then
  21.                 brr(Arr(i), 1) = brr(Arr(i), 0)
  22.                 brr(Arr(i), 2) = 1
  23.             ElseIf brr(Arr(i), 0) = brr(Arr(i), 1) Then
  24.                 brr(Arr(i), 2) = brr(Arr(i), 2) + 1
  25.             End If
  26.         Else
  27.             If brr(Arr(i), 2) = 0 Then brr(Arr(i), 2) = 1
  28.         End If
  29.     '到这里完成所有统计,下面是整理输出结果。
  30.     For i = 0 To 9
  31.         If brr(i, 2) > 0 Then StrT = StrT & vbCr & i & " Continue Max Count " & brr(i, 1) + 1 & ", Frequency " & brr(i, 2) & " times"
  32.     Next i
  33.     MsgBox "Continue Max Count Detail: " & StrT
  34. End Sub
复制代码
回复

使用道具 举报

发表于 2012-2-10 11:14 | 显示全部楼层
如果统计对象为整数,也还可以按此方法处理。

仅当统计对象元素为任意文本、货币、小数等数据时,才需要使用字典。
回复

使用道具 举报

发表于 2012-2-10 11:50 | 显示全部楼层
对于任意数据类型都有效的【字典定位+数组统计】代码如下:
  1. Sub DicCount()
  2.     Arr = Array(0, 1, 1, 1, 0, 0, 2, 2, 1, 3, 3, 0, 0, 1, 1, 1, 2, 3, 0, 2, 2)
  3.     Arr = Array("a", "a", "b", "a", "a", "a", "b", "b", "a", "a", "a", "d")
  4.    
  5.     ReDim brr(UBound(Arr), 3)
  6.    
  7.     Set d = CreateObject("Scripting.Dictionary")
  8.     m = 0:    d(CStr(Arr(0))) = m:    t = m:    brr(t, 0) = Arr(0)
  9.    
  10.     For i = 0 To UBound(Arr) - 1
  11.         If Arr(i) = Arr(i + 1) Then
  12.             brr(t, 1) = brr(t, 1) + 1
  13.         Else
  14.             If brr(t, 1) > brr(t, 2) Then
  15.                 brr(t, 2) = brr(t, 1)
  16.                 brr(t, 3) = 1
  17.             ElseIf brr(t, 1) = brr(t, 2) Then
  18.                 brr(t, 3) = brr(t, 3) + 1
  19.             End If
  20.             brr(t, 1) = 0
  21.             
  22.             t = d(CStr(Arr(i + 1)))
  23.             If t = "" Then m = m + 1:  d(CStr(Arr(i + 1))) = m:  t = m:  brr(t, 0) = Arr(i + 1)
  24.         End If
  25.     Next
  26.         If Arr(i) = Arr(i - 1) Then
  27.             If brr(t, 1) > brr(t, 2) Then
  28.                 brr(t, 2) = brr(t, 1)
  29.                 brr(t, 3) = 1
  30.             ElseIf brr(t, 1) = brr(t, 2) Then
  31.                 brr(t, 3) = brr(t, 3) + 1
  32.             End If
  33.         Else
  34.             If brr(t, 3) = 0 Then brr(t, 3) = 1
  35.         End If
  36.    
  37.     For i = 0 To m
  38.         StrT = StrT & vbCr & brr(i, 0) & " Continue Max Count " & brr(i, 2) + 1 & ", Frequency " & brr(i, 3) & " times"
  39.     Next i
  40.     MsgBox "Continue Max Count Detail: " & StrT
  41. End Sub
复制代码
这样的算法,效率是最高的。

尤其是数据量较大时,字典方法本身肯定比数组要慢。




回复

使用道具 举报

发表于 2012-2-10 11:54 | 显示全部楼层
对于同样的数据 Arr = Array(0, 1, 1, 1, 0, 0, 2, 2, 1, 3, 3, 0, 0, 1, 1, 1, 2, 3, 0, 2, 2)

3楼方法字典使用了 37次,而我的【字典定位+数组操作】方法,仅使用字典14次。速度大大提高。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-25 17:39 , Processed in 0.157445 second(s), 9 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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