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


    你现在要弄清楚一件事情:
如果有段重复了,你是删除前面的还是后面的!
行也是一样,从图片上看,很显然你现在删的是前面的
页: 1 [2] 3 4 5 6 7 8
查看完整版本: 删除重复行,为什么速度慢,帮看下代码(已解决)