shano
发表于 2010-11-12 19:33:33
看看BINGHC的源码是否支持不相邻的行
binghc
发表于 2010-11-12 19:41:31
本帖最后由 binghc 于 2010-11-12 22:53 编辑
回复 16# shano
你想要支持不相邻的行啊,这个容易,但问题是这样不往往有问题吗?
而且从效率考虑,每处理一行就要扫描整个文件的所有行,这样效率就低多了
fpquenya
发表于 2010-11-12 20:46:42
学习下高效代码!谢谢分享
3mile
发表于 2010-11-12 21:24:27
可惜AU3不支持HASH表,只能用数组完成。
没有完整测试过,可能会出现数组溢出的情况。
68K的数据用时1秒,扩展到2M用时42秒,几乎是成几何级递增。高手速度飘过。
#include <array.au3>
#include <file.au3>
Local $txt_array1,$time=TimerInit()
If FileExists('bb.txt') Then FileDelete('bb.txt')
_FileReadToArray('a.txt',$txt_array1)
Local $txt_array
For $i=0 To UBound($txt_array)-1
$txt_array[$i]=$txt_array1[$i]
$txt_array[$i]=$i+1
Next
_ArraySort($txt_array)
For $i=1 To UBound($txt_array)-1
If $txt_array[$i]==$txt_array[$i-1] Then $txt_array[$i-1]=0
Next
_arraysort($txt_array,0,0,0,1)
$hFile = FileOpen('bb.txt', 1)
For $i=0 To UBound($txt_array)-1
If $txt_array[$i]>1 Then FileWrite($hFile,$txt_array[$i]&@CRLF)
Next
FileClose($hFile)
MsgBox(0,TimerDiff($time),_FileCountLines('bb.txt'))
3mile
发表于 2010-11-12 21:26:51
如果数据量不大的情况直接用_ArrayUnique吧。免得麻烦。
laojikelly
发表于 2010-11-12 21:54:15
我看看。。。。。。。。。。。。。。。。。。
binghc
发表于 2010-11-12 22:17:07
本帖最后由 binghc 于 2010-11-12 22:51 编辑
本人的新作:删除相邻段(所有相邻的段,包括行)这里有必要说明一下,这里的相邻段是指广义上的相邻段
经本人测试:我下载了一部小说712k ,然后将整部小说复制粘贴在这部小说的结尾,也就是说现在这个文本有1.39M
处理1万行非空白行,整个过程耗时30秒(2.5Ghz电脑上测试)
尽管我的代码已经做过优化,但是要删除所有可能的相邻段,所需时间可想而知
下面是测试例子:
这是源码地址
http://www.autoitx.com/forum.php?mod=viewthread&tid=19646&page=1&extra=#pid231946
haodd
发表于 2010-11-12 22:36:15
学习!观摩 参考 这里还能学到挺多的嘛
pusofalse
发表于 2010-11-12 23:03:26
AU3支持Hash表的,Hash表的关键在于:关键字为k的记录,其必然存储在与k相关的地址中。
比如“Hello”,取其首字母H的Ascii码72,那么关键字为Hello的记录,必然会存储在表格中的72这个位置中。
楼主贴出的批处理代码就是利用了查表的方式,只不过把这里的Hash表理解为变量表更加合适。Au3中的Assign、Eval、IsDeclared不就是为此而存在的吗。
Assign - 向Hash表中添加记录。
Eval - 取Hash表中的记录。
IsDeclared - 判断表中是否记录着指定的关键字。
与表驱动类似,都是将关键字转为索引,利用此索引查表,但Hash表比表驱动更加强大,一般意义上,表驱动只能用一个不超出表格范围的数字作为索引,而Hash表所用的关键字索引则可以是 与记录相关的字符串或者数字。
看下这些帖子:
http://www.autoitx.com/search.php?searchid=459&orderby=lastpost&ascdesc=desc&searchsubmit=yes
nbmpe
发表于 2010-11-13 09:45:01
我随便看了下大家的回复,看批处理的思想好像是声明的方式,用我发的代码是对比的方向,声明只用检查一次就行了,效率会大大的提高。好像论坛中也有声明相关的代码,下午再看下。
3mile 兄的代码对我有点难度,好几个命令没用过。下午回来研究下!
lanfengc
发表于 2010-11-13 10:16:54
这个函数就可以了。。_ArrayUnique
binghc
发表于 2010-11-13 14:37:45
本帖最后由 binghc 于 2010-11-13 14:57 编辑
回复 19# 3mile
你的代码的有我没有的特点:就是能处理非相邻重复段。现在你的麻烦来了:
结果是文章的顺序都被打乱了
(相邻重复段也有这样的问题:http://www.autoitx.com/forum.php?mod=redirect&tid=19646&goto=lastpost#lastpost)
原文:
处理后:
3mile
发表于 2010-11-13 15:27:24
回复 27# binghc
写成函数形式,使用REDIM,也许效率会下降.
不知道解决了排序出错的问题了吗?请测试下.
#include <array.au3>
#include <file.au3>
Local $aArray,$time=TimerInit()
_FileReadToArray('test.txt',$aArray)
$count=$aArray
_ArrayDelete($aArray,0);删除总行数,避免排序出错
$aa = _unique($aArray)
MsgBox(0,'用时:'&TimerDiff($time),'总行数:'&$count)
_ArrayDisplay($aa)
Func _unique($aArray)
If Not IsArray($aArray) Then Return SetError(1);非数组
Local $rows = UBound($aArray), $cols = UBound($aArray, 2), $dims = UBound($aArray, 0)
If $dims > 2 Then Return SetError(2);非一维或二维数组
If $dims = 2 Then
Local $temp[$rows][$cols + 1]
For $n = 0 To $cols
If $n < $cols Then
For $i = 0 To $rows - 1
$temp[$i][$n] = $aArray[$i][$n]
Next
Else
For $i = 0 To $rows - 1
$temp[$i][$n] = $i
Next
;_ArrayDisplay($temp)
EndIf
Next
_ArraySort($temp)
For $i = 1 To $rows - 1
If $temp[$i] == $temp[$i - 1] Then $temp[$i - 1][$cols] = -1
Next
_ArraySort($temp, 0, 0, 0, $cols)
Local $k = 0, $y = 0, $p = 0, $reules[$cols]
For $n = 0 To $cols - 1
For $i = 1 To $rows - 1
If $temp[$i][$cols] > -1 Then
$p = UBound($reules)
ReDim $reules[$p + 1][$cols]
$reules[$k][$n] = $temp[$i][$n]
$k += 1
If $reules[$p - 1] == '' Then _ArrayDelete($reules, $p - 1)
EndIf
Next
$k = $y
$y += 1
Next
_ArrayDelete($reules, UBound($reules) - 1)
Return $reules
Else
Local $temp[$rows]
For $i = 0 To $rows - 1
$temp[$i] = $aArray[$i]
$temp[$i] = $i
Next
_ArraySort($temp)
For $i = 1 To UBound($temp) - 1
If $temp[$i] == $temp[$i - 1] Then $temp[$i - 1] = -1
Next
_ArraySort($temp, 0, 0, 0, 1)
Local $k=0,$reules
For $i=0 To UBound($temp)-1
If $temp[$i]=-1 Then ContinueLoop
ReDim $reules[$k+2]
$reules[$k]=$temp[$i]
$k+=1
Next
_ArrayDelete($reules,UBound($reules))
Return $reules
EndIf
EndFunc ;==>_unique
binghc
发表于 2010-11-13 15:48:26
本帖最后由 binghc 于 2010-11-13 16:00 编辑
回复 28# 3mile you
问题没解决,处理时间倒是变长了许多
binghc
发表于 2010-11-13 16:03:23
回复 28# 3mile
你现在要弄清楚一件事情:
如果有段重复了,你是删除前面的还是后面的!
行也是一样,从图片上看,很显然你现在删的是前面的