找回密码
 加入
搜索
查看: 2255|回复: 9

[效率算法] 如何高效删除二维数组空值行

[复制链接]
发表于 2019-10-21 21:38:00 | 显示全部楼层 |阅读模式
本帖最后由 xymc 于 2019-10-22 20:30 编辑
#include <Array.au3>
Dim $Array[5][2] = [["", ""], ["23", 51], ["", ""], ["55", 34], ["67", 98]]
_arraydisplay($Array, ' ')
For $i = UBound($array) -1 To 0 Step -1
If $array[$i][1] =="" Then _ArrayDelete($array,$i)
Next
_arraydisplay($Array, ' ')
A01        0f10793e57152d5f0c2362a5e344aa18

A02        394a93b2dee0af80fe3dc0d2e055dd94
A03        5c7ae8a9afbeb91b8c96afd59bb08e85

A04        ea67946932abcaa36e4e8fe8300e0782

A05        272d07a2676617413ba7bb535bf38456

A06        9ca87ea6b913e96bcea2418c705a5f9b
A07        bd0ae8c2d1c1d51481fcdfc4f5d658df

A08        d7cb800c46e197b2d2447a7b2da72afb



如果是几千行数据的话,效率太慢了
有什么高效的办法删除二维数组空值行
发表于 2019-10-24 10:10:20 | 显示全部楼层
EmEditor,删除空行功能
发表于 2019-10-24 12:01:50 | 显示全部楼层
本帖最后由 make2855 于 2019-10-24 12:05 编辑

显然,你的方法是很慢的。
说说我的思路:
1. 首先声明一个同样大小的数组,数组大小与原数组相同
2. 循环检查原数组值是否为空,不为空的值拷贝到新数组,同时记录拷入的数量
3. 根据拷入数切断新数组尾部多余空位
4. 新数组覆盖旧数组
代码如下:
#include <Array.au3>
Dim $Array[5][2] = [["", ""], ["23", 51], ["", ""], ["55", 34], ["67", 98]]
_arraydisplay($Array, ' ')
dim $a2[UBound($Array)][2]
dim $j
For $i = UBound($array) -1 To 0 Step -1
        If $array[$i][1] <> "" Then
                $a2[$j][0] = $array[$i][0]
                $a2[$j][1] = $array[$i][1]
                $j += 1
        EndIf
Next
ReDim $a2[$j][2]


发表于 2019-10-25 11:49:52 | 显示全部楼层
犯错是有利于成长的,这是因为出错会让人反思,反思更好的

不做死就不会死, 发自内心的对字典的热爱,我尝试了3种字典法,结果自己写的字典法完败…………
发表于 2019-10-25 11:51:13 | 显示全部楼层
#include <Array.au3>
$num_test=10000
Dim $Array[$num_test][2]
For $i = 0 To $num_test-1
        If Mod($i,2)=0 Then
          $Array[$i][0]=Random(1,100,1)
          $Array[$i][1]=Random(1,100,1)+$i*200  ;*200:构建不同的数值,避免写入时候的重复
        else
          $Array[$i][0]=''
          $Array[$i][1]=''
        EndIf
Next       
;_arraydisplay($Array, '构建数组 ')

#cs
;方法一:效率过慢,测试数量太多的时候,等待时间久,舍弃测试
$time = TimerInit()
For $i = UBound($array) -1 To 0 Step -1
If $array[$i][1] =="" Then _ArrayDelete($array,$i)
Next
$time = TimerDiff($time)
ConsoleWrite( @crlf &'_ArrayDelete 用时:'&$time&@crlf)
;_arraydisplay($Array, '_ArrayDelete结果 ')
#ce
;方法2:解释详见楼上,;直接伸手………………借用楼上的代码进行测试
$time = TimerInit()
dim $a2[UBound($Array)][2]                       
dim $j
For $i = 0 To UBound($array) -1
        If $array[$i][1] <> "" Then
                $a2[$j][0] = $array[$i][0]
                $a2[$j][1] = $array[$i][1]
                $j += 1
        EndIf
Next
ReDim $a2[$j][2]
$time = TimerDiff($time)
ConsoleWrite( @crlf &'ReDim新数组 用时:'&$time&@crLF)
;_arraydisplay($a2, '写入新数组 结果 ')

;方法3:单字典入key+_arraytostring+StringSplit+数组重新赋值
$time=TimerInit()
$obj=ObjCreate('scripting.dictionary')
For $i=0 To UBound($array) -1         
                If $array[$i][1] <> "" Then                  ;根据需要自行更改
                        $obj.add($array[$i][0]& '|'&$array[$i][1] & '|' &$i,0) ;满足条件的非空数值写入字典,加上&i,避免小概率的重复事件
        EndIf
Next
$tmp=$obj.keys()
$str=_arraytostring($tmp)
$tmp_new=StringSplit($str,'|')
dim $a3[UBound($tmp)][2]
For $i = 0 To UBound($tmp)-1
        For $j = 0 To 1
                $a3[$i][$j]=$tmp_new[$i*3+$j+1]
        Next       
Next       
$obj.RemoveAll
$time=TimerDiff($time)
ConsoleWrite( @crlf &'单字典入key+2次String操作 总用时:'&$time&@crLF)
;_arraydisplay($a3, '单字典入key+2次String操作 ')

;方法4:双字典items+数组重新赋值
$time=TimerInit()
$d0=ObjCreate('scripting.dictionary')
$d1=ObjCreate('scripting.dictionary')
For $i=0 To UBound($array) -1         
                If $array[$i][1] <> "" Then                  ;根据需要自行更改                       
                        $d0.add($i,$array[$i][0]) ;满足条件的非空数值写入字典,加上&i,避免小概率的重复事件
                        $d1.add($i,$array[$i][1]) ;满足条件的非空数值写入字典,加上&i,避免小概率的重复事件
        EndIf
Next
$tmp0=$d0.items();keys()
$tmp1=$d1.items();.keys()
dim $a3[UBound($tmp0)][2]
For $i = 0 To UBound($tmp)-1       
        $a3[$i][0]=$tmp0[$i]
        $a3[$i][1]=$tmp1[$i]
Next
$d0.RemoveAll
$d1.RemoveAll
$time=TimerDiff($time)
ConsoleWrite( @crlf &'双字典对象去重法总用时:'&$time&@crLF)
;_arraydisplay($a3, '双字典+items操作')

;方法5:考虑到2个数值明显的不同,1 字典 key +item+数组重新赋值;
$time=TimerInit()
$d0=ObjCreate('scripting.dictionary')
;$d1=ObjCreate('scripting.dictionary')
For $i=0 To UBound($array) -1         
                If $array[$i][1] <> "" Then                  ;根据需要自行更改;满足条件的非空数值写入字典,加上&i,避免小概率的重复事件
                        $d0.add($array[$i][1],$array[$i][0]) ;满足条件的非空数值写入字典,加上&i,避免小概率的重复事件                       
        EndIf
Next
$tmp0=$d0.keys()
$tmp1=$d0.items()
dim $a3[UBound($tmp0)][2]
For $j = 0 To UBound($tmp)-1       
        $a3[$j][0]=$tmp1[$j]
        $a3[$j][1]=$tmp0[$j]
Next       
$d0.RemoveAll
$time=TimerDiff($time)
ConsoleWrite( @crlf &'1字典+特征无重复key值可用 用时:'&$time&@crLF)
;_arraydisplay($a3, '1字典+特征无重复key值')
发表于 2019-10-25 11:54:26 | 显示全部楼层
make2855  的办法是 最快的,直接判断后写入数组,节省了大量的不必要的步骤,
字典法此次完败,是我没有找到正确的路径???

测试耗时结果:
>运行:(3.3.7.15):D:\autoit3\参考资料\AutoIt(AU3) v3.3.7.15 汉化绿色版\autoit3\autoit3_x64.exe "C:\Users\Administrator\Desktop\双字典对象去重.au3"   

ReDim新数组 用时:60.3104554201411

单字典入key+2次String操作 总用时:234.050032071841

双字典对象去重法总用时:197.223348300192

1字典+特征无重复key值可用 用时:133.497883258499
发表于 2019-10-25 13:43:24 | 显示全部楼层
试试数组转字符串处理, demo只处理列数为2的二维数组,默认数组内容无符号“|” 和 @CRLF, 如果有需要进一步改造

游客,如果您要查看本帖隐藏内容请回复

发表于 2019-10-25 16:31:08 来自手机 | 显示全部楼层
好强大的正则,好快的速度!
发表于 2019-10-25 16:32:53 | 显示全部楼层
floor6ggg 发表于 2019-10-25 11:54
make2855  的办法是 最快的,直接判断后写入数组,节省了大量的不必要的步骤,
字典法此次完败,是我没有 ...

个人认为字典适合做索引来减少计算量,而这种整理的工作索引的用途有限,基本上还是控制循环数量的问题,所以字典败了也很正常,毕竟创建和写入字典对象也要多耗点时间
发表于 2019-12-19 21:09:14 | 显示全部楼层
学习下是怎么实现的
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-4-27 07:53 , Processed in 0.076192 second(s), 19 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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