找回密码
 加入
搜索
查看: 11941|回复: 25

[效率算法] 向各位路过的老师请教下关于文件行数及数组问题[已解决]

 火... [复制链接]
发表于 2011-5-19 22:50:54 | 显示全部楼层 |阅读模式
本帖最后由 annybaby 于 2011-5-20 00:31 编辑

具体描述如下:

我经常需要处理一些文本文件,将文件逐行读出,并将它放到一个数组里面进行后续的处理,文件的行数会有比较大的差别,怎样得到这个行数及申请数组的会比较好呢?
我知道,可以用一个循环来读取,定义一个记录行数的变量,每读一行就加1,直至文件末尾,或者直接用自定义函数_FileCountLines(),还有其它好一点的方法吗?主要考虑的是代码长度,资源占用,执行效率以及编译后文件的大小,特别是数组申请问题,每次都处理不好,太大的话觉得浪费系统资源(会吗?)太小又容易越界~
发表于 2011-5-19 22:59:23 | 显示全部楼层
现成的函数呀:

#include <File.au3>
#include <Array.au3>

Local $Array
_FileReadToArray("F:\test.txt", $Array)

_ArrayDisplay($Array)

发表于 2011-5-19 23:21:43 | 显示全部楼层
#include <Array.au3>
Local $sText    = FileRead("test.txt")
Local $asResult = StringRegExp($sText, '(.*)\r\n', 3)
_ArrayDisplay($asResult, "行数: " & UBound($asResult))
Exit
 楼主| 发表于 2011-5-19 23:34:44 | 显示全部楼层
回复 2# happytc


    这个只是显示出来吧?我还要对数据进程比较复杂的处理的,如说,要对每行数据进行分割,对其中一部分进行运算,交换位置等
发表于 2011-5-19 23:41:33 | 显示全部楼层
本帖最后由 love5173 于 2011-5-19 23:58 编辑

回复 1# annybaby
关于这个问题,我也没有搜索别人的回答,我是这么理解的
搜索整个文本内的换行也就是\n的个数,理想状态下最后一行是没有换行符的,也就是搜索\n的个数+1 就是整个文本的行数,但是考虑到有的文本不是很整齐,里面会夹杂着好几个换行的情况,这时要先把连续的换行替换为一个换行,也就是\n{2,}替换为\n,但是这样仍然存在着最后一行后面或许还是有一个换行,这样就需要判断最后一个换行后面还有没有字符,索性开始的时候直接给最后一行加上一个换行就是了,经过替换后,含有的换行个数就是楼主要的内容了。
代码如下
$con=UBound(StringRegExp(StringRegExpReplace(FileRead("txt.txt")&@CRLF,'(\n){2,}','\1'),'\n',3))

考虑的代码做过的运算内容未必有楼主说的快,希望楼主经过测试后,觉得满意再使用
另外,楼主只是为了要把每行都读到数组里面的话,可以用
$array=StringRegExp(fileread("txt.txt"),'[^\n]+',3)
$con=UBound($array)
来实现,当然,也有现成的UDF
 楼主| 发表于 2011-5-19 23:48:53 | 显示全部楼层
本帖最后由 annybaby 于 2011-5-20 00:02 编辑

回复 3# easefull

这个不错,我看了一下,自定义函数_FileCountLines()也是通过正则来计算行数,不过调用的话会多打开一次函数,所以直接用前面已经打开的应该会快一些,呵呵,谢谢指教~~

不过总行数是比数组长度UBound()大1,因为最后一行是没有回车换行的~~
发表于 2011-5-19 23:54:52 | 显示全部楼层
回复 4# annybaby

它已经把每行读到一个数组元素里,第一个元素是这个文件里有多少行

这样,无论你怎样复杂操作,你不就是对这个数组进行操作就可以了
怎么叫“显示”出来呢?????
发表于 2011-5-19 23:57:24 | 显示全部楼层
本帖最后由 love5173 于 2011-5-20 00:01 编辑

回复 3# easefull
你的代码表面看起来没有问题,但是如果你能看看我上面说的内容的话就会发现,你的代码存在致命的缺陷,5楼的代码已经更新,你可以看看下面那个,
经过我对10010行文件的测试,我的第一个取行数的代码,比第二个慢了一倍差不多,呵呵!
你的正则有问题,要么改正则,如果非要这么写,那么就要做我上面说的做换行的处理
发表于 2011-5-20 00:10:25 | 显示全部楼层
回复 8# love5173
\r\n分行,你是用的\n分行.
很难说谁的代码存在致使的缺陷
发表于 2011-5-20 00:14:56 | 显示全部楼层
本帖最后由 love5173 于 2011-5-20 00:24 编辑

回复 9# 3mile
欢迎测试,我希望你能看完我的5楼再说。如果你的最后一行根本后面就没有换行符呢,你是怎么判断的?这不是致命缺陷吗?
而我用的\n也不是绝对的,要根据实际的文件处理,因为我处理的是txt,作为txt 3M应该知道换行是\n\r,我的代码绝对没有问题!
如果你找出错误我愿意给你道歉!
更正一下@crlf 是\r\n , 其实无论是\r\n 还是\n\r 都不会影响我的第一行代码的计算的,当然那个确实慢。
5楼我是给的两个代码,第一行只是一个思路而已,目的不是在于那句代码,而是在给大家说一些事情而已。
授人以鱼不如授人以渔!
发表于 2011-5-20 00:25:08 | 显示全部楼层
回复 10# love5173
File.au3里的这段函数已经很说明问题了.
Func _FileCountLines($sFilePath)

        Local $hFile = FileOpen($sFilePath, $FO_READ)
        If $hFile = -1 Then Return SetError(1, 0, 0)
        Local $sFileContent = StringStripWS(FileRead($hFile), 2)
        FileClose($hFile)
        Local $aTmp
        If StringInStr($sFileContent, @LF) Then
                $aTmp = StringSplit(StringStripCR($sFileContent), @LF)
        ElseIf StringInStr($sFileContent, @CR) Then
                $aTmp = StringSplit($sFileContent, @CR)
        Else
                If StringLen($sFileContent) Then
                        Return 1
                Else
                        Return SetError(2, 0, 0)
                EndIf
        EndIf
        Return $aTmp[0]
EndFunc   ;==>_FileCountLines

你的那段代码只考虑了@LF, @CRLF作为换行的处理.难道@CR不能作为换行?
不是想要你给谁道歉才写的这段.
发表于 2011-5-20 00:28:48 | 显示全部楼层
回复 11# 3mile
关于对换行符的支持问题,我想你比我更了解,作为TXT换行的话,你说有几种形式?
 楼主| 发表于 2011-5-20 00:30:19 | 显示全部楼层
谢谢楼上几位老师的热心解答~~
发表于 2011-5-20 00:30:35 | 显示全部楼层
回复  3mile
关于对换行符的支持问题,我想你比我更了解,作为TXT换行的话,你说有几种形式?
love5173 发表于 2011-5-20 00:28

你当然比我了解的多,请教
发表于 2011-5-20 00:38:05 | 显示全部楼层
本帖最后由 love5173 于 2011-5-20 00:44 编辑

其他文件类型我不清楚,但是我电脑上txt的换行都是0d0a
算了,不想争什么了,我会努力学习的!同时我也承认我的代码有致命的缺陷!以后也不会乱说话了!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-6 15:54 , Processed in 0.084991 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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