3mile
发表于 2010-11-13 16:16:13
回复 30# binghc
加个判断应该可以了.
不使用Redim函数应该可以提高些效率.
#include <array.au3>
#include <file.au3>
Local $aArray,$time=TimerInit()
_FileReadToArray('test.txt',$aArray)
Global $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];,$k=$count,$p=0
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
$min=_Min($temp[$i],$temp[$i - 1])
$temp[$min] = -1
;$k-=1
EndIf
Next
_ArraySort($temp, 0, 0, 0, 1)
Local $k=$count
For $i=0 To UBound($temp)-1
If $temp[$i]=-1 Then $k-=1
Next
Local $reules[$k+1],$p
For $i=0 To UBound($temp)-1
If $temp[$i]=-1 Then ContinueLoop
$reules[$p]=$temp[$i]
$p+=1
Next
Return $reules
EndIf
EndFunc ;==>_unique
Func _Min($nNum1, $nNum2)
If (Not IsNumber($nNum1)) Then Return SetError(1, 0, 0)
If (Not IsNumber($nNum2)) Then Return SetError(2, 0, 0)
If $nNum1 > $nNum2 Then
Return $nNum2
Else
Return $nNum1
EndIf
EndFunc ;==>_Min
binghc
发表于 2010-11-13 16:26:29
本帖最后由 binghc 于 2010-11-13 16:30 编辑
回复 31# 3mile
嗯,没错,是比上一个快了点,但是。。。。
我纳闷了,你这是要什么效果?
3mile
发表于 2010-11-13 16:35:15
回复 32# binghc
哈哈,我自己也郁闷了.
正在修改中,想法大概有了吧.
顺便请你将测试文本也发上来吧.
binghc
发表于 2010-11-13 16:43:43
本帖最后由 binghc 于 2010-11-13 16:44 编辑
回复 33# 3mile
嗯,好!就是这本小说,怕扣钱也可以自己网上下载,这是小说原文本,没改。测试的时候自己稍微改一下
3mile
发表于 2010-11-13 17:59:22
回复 34# binghc
请帮忙再测试下吧.多谢
但是效率应该下降了些.
#include <array.au3>
#include <file.au3>
Local $aArray,$time=TimerInit()
_FileReadToArray('萌动校园.txt',$aArray)
Global $count=$aArray
_ArrayDelete($aArray,0);删除总行数,避免排序出错
$aa = _unique($aArray)
MsgBox(0,'用时:'&TimerDiff($time),'总行数:'&$count)
_FileWriteFromArray('输出.txt',$aa)
_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];,$k=$count,$p=0
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
If $temp[$i]>$temp[$i - 1] Then
_ArrayDelete($temp,$i)
$i-=1
Else
_ArrayDelete($temp,$i-1)
$i-=1
EndIf
EndIf
If $i=UBound($temp)-1 Then ExitLoop
Next
_ArraySort($temp, 0, 0, 0, 1)
Local $reules,$p
For $i=0 To UBound($temp)-1
If $temp[$i]=-1 Then ContinueLoop
$reules[$p]=$temp[$i]
$p+=1
Next
Return $reules
EndIf
EndFunc ;==>_unique
Func _Min($nNum1, $nNum2)
If (Not IsNumber($nNum1)) Then Return SetError(1, 0, 0)
If (Not IsNumber($nNum2)) Then Return SetError(2, 0, 0)
If $nNum1 > $nNum2 Then
Return $nNum2
Else
Return $nNum1
EndIf
EndFunc ;==>_Min
Func _Max($nNum1, $nNum2)
; Check to see if the parameters are indeed numbers of some sort.
If Not IsNumber($nNum1) Then Return SetError(1, 0, 0)
If Not IsNumber($nNum2) Then Return SetError(2, 0, 0)
If $nNum1 > $nNum2 Then
Return $nNum1
Else
Return $nNum2
EndIf
EndFunc ;==>_Max
binghc
发表于 2010-11-13 18:26:06
回复 35# 3mile
现在基本上没问题(网速慢上传不了图片),'萌动校园.txt'这本小说,你用这个处理需多长时间啊?
(现在可以去处理一下我之前说的不能处理的向同行)
萌动校园
萌动校园ooo
binghc
发表于 2010-11-13 18:35:59
数组插入排序法确实是很快,我刚才还是发现了:
文中有很多相同的行,不是重复的,比如: “……”
你找找看,像这种的话就属于误删了
这种算法是对数组进行排序,再处理,所以速度要快很多
但是如果要做到非相邻行相同不删除,也就是说只删除相同相邻行
能不能做到呢,这种算法?
3mile
发表于 2010-11-13 20:20:07
回复 37# binghc
刚才是单位的电脑,现在已经下班,没法测试时间了。
用家里的电脑测了下,配置是X2 4400+,2G内存。测试“萌动校园”小说用时10447毫秒,大约10秒多11秒吧。
如果要做到非相邻行相同不删除,也就是说只删除相同相邻行的话只用_ArrayDelete吧。
binghc
发表于 2010-11-13 21:00:09
看来我的电脑比你好啊,哈哈!我用了9秒,我用自己的代码测试用了10秒。不过单位电脑比你单位垃圾多了
3mile
发表于 2010-11-13 22:28:31
回复 39# binghc
呵呵,你那个代码我用了12秒。
几千行数据要处理,不在乎那几秒钟的时间。
afan
发表于 2010-11-13 22:34:23
本帖最后由 afan 于 2010-11-13 22:42 编辑
回复 40# 3mile
用正则估计不会超过一秒,不过,此题没啥实用意义的说~ 如果是小说之类的,重复行(段)是完全可能正常存在的,用在这里肯定不合适~
倒是仅删除所有的重复行可能会有用,用P版在24#所说的方法或使用正则应该比用数组操作快许多倍~
3mile
发表于 2010-11-13 22:44:33
回复 41# afan
呵呵,确实没啥意义啊。
只是比较郁闷楼主所说的30多M的大文本哈。
afan
发表于 2010-11-13 22:52:36
回复 42# 3mile
呵呵 貌似LZ都不关心本帖,倒是大家十分热心~
binghc
发表于 2010-11-13 23:16:29
本帖最后由 binghc 于 2010-11-13 23:19 编辑
呵呵,我们也不知道楼主是啥意思,他说有两个文件,我问了,他也没说
我们现在视乎在借楼主的提问,衍生到另外一个话题。由一开始的相邻重复行到相邻重复段,
然后又是非相邻的重复。
不过看了“三笑”兄的代码,本人现在对数组的排序算法倒是很感兴趣,虽然以前在学校学过一
点数组排序算法,现在有点陌生。研究了大半天,现在终于有点明白_arraysort()这个函数的数组排序算法
是怎么回事,现在继续研究。。。。。{:face (270):}
顺便发一下感慨:通过别人的代码读别人的思想真的是一件令人头疼的事!
nbmpe
发表于 2010-11-14 11:31:56
不是不热心,这个周末时间不多呀,我处理的文档是这样的,这把下面的复制一千次就行了。处理后的结果是下面的内容。
AAA BBB
CCC AAA
AB AB AC
ABCDE AAA