ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 恳请! 算法高手…出手帮忙解难题…

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-1-23 19:16 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
648555205 发表于 2018-1-23 18:57
看不到你的原始数据,不知道到底是为什么

你用find查找的时候是否注意了星号通配符的问题,因为我看你 ...

老师, 不是的这样的,

我是用计算结果的一两个重复值,

再到原始数据(一列)的页面去FIND重复值,
找到的行数, 是比答案多了一些

TA的精华主题

TA的得分主题

发表于 2018-1-23 19:47 | 显示全部楼层
On_fire 发表于 2018-1-23 19:16
老师, 不是的这样的,

我是用计算结果的一两个重复值,


可不可能有这种情况呢?比如: 1.jpg

由于通配符的影响,Find查找出来的和实际的数字是不一样的

TA的精华主题

TA的得分主题

发表于 2018-1-23 21:34 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
On_fire 发表于 2018-1-20 15:44
算法要求都说了, 没有说明甚么?

同样愚钝,你的示例跟你的说明完全不匹配,不懂你要做什么。

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-1-23 21:48 | 显示全部楼层
本帖最后由 On_fire 于 2018-1-23 22:02 编辑
Nhand 发表于 2018-1-23 21:34
同样愚钝,你的示例跟你的说明完全不匹配,不懂你要做什么。

老师,

不是太明白你的意思…请问那一句不匹配? 那一句不懂?

示例 (简化的)=截图/文件, 计算要求也有说明了..

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-1-23 21:56 | 显示全部楼层
Nhand 发表于 2018-1-23 21:34
同样愚钝,你的示例跟你的说明完全不匹配,不懂你要做什么。

香川老師,

对这个问题的理解是:

1. 循环遍历m行
2. 以该行各个元素(=每单元格)为检查对象,循环遍历所有其它行,记录元素匹配个数
3. 按匹配个数最多、元素个数最多的顺序返回、输出查询结果

做法很简单,写个双循环(实质为行对行、列对列的4层循环)即可完成,
但是为了提高计算效率,需要做很多细致的算法改进。

最快和最慢的,可以相差几十到几千倍。

TA的精华主题

TA的得分主题

发表于 2018-1-24 09:16 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
On_fire 发表于 2018-1-23 21:56
香川老師,

对这个问题的理解是:

是的,下面是不考虑效率的基本算法的伪代码:

Sub test()
   
    m = 8: n = 13
    ar = [a1].Resize(m, n) '读取工作表中m行、n列的原始数据
   
    For i = 1 To m '遍历各行,以本行 i 行作为比较标准
        For i2 = 1 To m '遍历各行进行匹配比较
            If i2 <> i Then '排除本行
                r = 0 '统计匹配相同个数的变量r初始化
                For j = 1 To n '遍历本行各列 j
                    t = ar(i, j)
                    If Len(t) Then '如果非空单元格
                        For j2 = 1 To n '遍历比较 i2行的各列 j2
                            If ar(i2, j2) = t Then r = r + 1: Exit For
                        Next
                    End If
                Next
                '此处得到匹配结果: i2行和本行i的匹配相同个数r
                '然后还需要统计i2行的有效单元格个数 k2
            End If
        Next
        '然后在这里,对各个有效匹配行的匹配结果进行降序排序,并输出结果
    Next
    '计算完成
End Sub

这是最基本的算法,
改进以后,计算效率可以提高几千几万倍。

TA的精华主题

TA的得分主题

发表于 2018-1-24 09:18 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
On_fire 发表于 2018-1-23 21:56
香川老師,

对这个问题的理解是:

可以提供100-500行,100多列的实际数据,供大家写代码测试。

TA的精华主题

TA的得分主题

发表于 2018-1-24 09:36 | 显示全部楼层
本帖最后由 Nhand 于 2018-1-24 09:38 编辑

这个问题跟我不太相关,因为俺不是个程序猿,所以具体的代码就不去写了,一是没有数据,二是debug很麻烦~~~但是提供下个人思路
1 建立字典,将3W行的数据每个单元格都放入字典。把3W行的数据每个都遍历一次这个是必不可少的。。。不可省略步骤,但是先将range设置成 数组,遍历会稍微加快些速度,然后就是怎样建立字典。将每个单元格的值作为key,将单元格所在的行号做为item。然后,用d.exists判断是否存在某个单元格,如果存在,那么就是d(单元格内容)= 行号X & "+" & 行号y  意思就是,比如 第一行有字母a  就该是d(a)=1 第二行有字母a 就成了d(a)=1 & "+" 2,遍历完了之后就进入第二步,因为是d.exists判断,外加数组依次遍历,这个过程应该不会用太长时间吧?
2  item 存放的是 1+2  1+3+4 1+6+7等等内容。这个时候,将item的数据全部提取变成新字典的key。问题就变成了1+2  1+3+4 1+6+7 2+3 2+5+8一共最多3百万条数据,最少1条数据的问题了。特别的,这个新字典key的内容 都是行号从小到大排列好了的。所以新问题就变成了1+2 1+3+4 等筛选的问题,或者设置成1 2                       1 3 4这样做key 怎样做key你可以探讨下。因为直接提取行号了,就变成了归类的问题。这样的思路可否?

TA的精华主题

TA的得分主题

发表于 2018-1-24 09:44 | 显示全部楼层
Nhand 发表于 2018-1-24 09:36
这个问题跟我不太相关,因为俺不是个程序猿,所以具体的代码就不去写了,一是没有数据,二是debug很麻烦~~~ ...

进一步的,因为 1+2  1+3+5 2+5  5+9 因为每个key的第一个数字到最后一个数字都是从小到大的。那么问题就相对更简单点,遍历每个key,然后只取split(key,"+")(0)   比如这个值是5 那么就直接加入第5行数据段内容,遍历完key 事情也就做完了(注意没有+的情况),即1次循环!。大概是这样

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-1-24 09:52 | 显示全部楼层
香川群子 发表于 2018-1-24 09:16
是的,下面是不考虑效率的基本算法的伪代码:

Sub test()

谢谢老师补充说明…
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-27 06:01 , Processed in 0.034114 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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