找回密码
 加入
搜索
楼主: netbean

[效率算法] 文本减肥:正则[已解决]

 火.. [复制链接]
发表于 2011-5-1 19:54:58 | 显示全部楼层
本帖最后由 love5173 于 2011-5-2 11:01 编辑

回复 26# easefull
知道为什么我的代码这么慢么?
\x00----\x20
发表于 2011-5-1 20:04:34 | 显示全部楼层
回复 31# love5173


那时候我都是直接用记事本把第一行给删了保存,然后直接测试正则的^_^
发表于 2011-5-1 20:14:02 | 显示全部楼层
回复 32# easefull
你说的操作可以用程序实现的,应该比较快
发表于 2011-5-1 21:33:03 | 显示全部楼层
本帖最后由 kevinch 于 2011-5-1 21:34 编辑

再测试一下
发表于 2011-5-1 23:53:40 | 显示全部楼层
还是用正则来提高效率吧.
#include <array.au3>
$time=TimerInit()
$txt=FileRead("SNT.txt")
$temp=StringRegExpReplace($txt,'\x00',' ')
$str=StringRegExpReplace($temp,'(\d{6})\h+\H+\h+\H+\h+(.*?)(?=\h+)','\1-\2')
$str_array=StringRegExp($str,'\d{6}\-.*?(?=\h{8,})',3)
if FileExists("output.txt") then FileDelete("output.txt")
FileWrite("output.txt",_ArrayToString($str_array,@CRLF))
msgbox(0,0,"用时:"&TimerDiff($time)&"毫秒")

评分

参与人数 1金钱 +10 收起 理由
netbean + 10

查看全部评分

发表于 2011-5-2 02:13:03 | 显示全部楼层
本帖最后由 love5173 于 2011-5-2 02:34 编辑

回复 35# 3mile
学习了正则不熟练害死人啊,刚才我还跟人家说正则不能区分16进制的00归属问题,实在是汗颜啊
$time=TimerInit()
$txt=FileRead("shex.tnf")
$new=StringRegExpReplace($txt,'\x00',' ')
$new=StringRegExpReplace($new,'(?s).*?(\d{6})\h+\H+\h+\H+\h+(.*?)\h{10,}.*?','\1----\2'&@CRLF)
$now=TimerDiff($time)
MsgBox(0,"",$now)
FileOpen("new.txt",2+8)
FileWrite("new.txt",$new)
fileClose("new.txt")

631ms

评分

参与人数 1金钱 +10 收起 理由
netbean + 10 非常感谢

查看全部评分

 楼主| 发表于 2011-5-2 08:14:57 | 显示全部楼层
非常感谢!实验数据:
8支股票转换代码
4712/4914/4858ms-字典搜索
7718/7701/7182ms-字典建立/搜索
6061/6220/5411ms-StringInStr搜索
13493/12796/13516ms-StringInStr原始文本搜索

文本减肥
2958/3024/2981ms-记事本另存文本,by kevinch
2792/2756/2408/2425/2305/2326ms-记事本另存文本,by 3mile
10771/10897/10527ms-原始文本,by 3mile
1198/1293/1098ms-记事本另存文本,by love5173
9476/9283/9525ms-原始文本,by love5173

经过文本减肥,搜索代码的速度快了一倍多,很有效。
还有改进的空间吗?
发表于 2011-5-2 10:59:46 | 显示全部楼层
610ms,应该比较快了
$time=TimerInit()
$search="000010" ;要查询的股票编码号
$txt=FileRead("shex.tnf")
$new=StringRegExpReplace($txt,'\x00',' ')
$new=StringRegExpReplace($new,'(?s).*'&$search&'\h+\H+\h+\H+\h+(.*?)\h{10,}.*','\1')
$now=TimerDiff($time)
MsgBox(0,"用时"&$now,"股票名称为:"&$new)
 楼主| 发表于 2011-5-2 11:19:15 | 显示全部楼层
本帖最后由 netbean 于 2011-5-2 13:19 编辑

直接查询呵。能不能改成:以减肥后new.txt,输入名称查代码?
$new=StringRegExpReplace($new,'^(\d{6})\h+'&$search&'$','\1')

错在哪?
发表于 2011-5-2 12:07:03 | 显示全部楼层
本帖最后由 love5173 于 2011-5-2 14:47 编辑

回复 39# netbean
效果是一样的,否则你还要单独减肥一次,还不到1秒,也不慢,为什么非要减肥后的呢
$time=TimerInit()
$search="180运输" ;要查询的股票名称,要保持唯一性,否则只显示一个
$txt=FileRead("shex.tnf")
$new=StringRegExpReplace($txt,'\x00',' ')
$new=StringRegExpReplace($new,'(?s).*(\d{6})\h+\H+\h+\H+\h+'&$search&'\h{10,}.*','\1')
$now=TimerDiff($time)
MsgBox(0,"用时"&$now,"股票编号为:"&$new)
发表于 2011-5-2 14:04:25 | 显示全部楼层
本帖最后由 easefull 于 2011-5-3 11:25 编辑

效率测试,从原始文件到查询出结果的时间.
;version: 0.1.2 Beta
#include <Array.au3>
Local $SearchKey = InputBox("查询", "请输入股票名称或代码")
Local $iTime = TimerInit()
Local $oFile, $sText
$oFile = FileOpen("shex.tnf", 16)
$sText = FileRead($oFile)
$sText = StringRegExpReplace($sText, '(.{2})',  '\1' & " ")
FileClose($oFile)

Local $sRegExp  =         _
                                        '3\d\s3\d\s3\d\s3\d\s3\d\s3\d\s' & _
                                        '00\s00\s00\s' & _
                                        '..\s'  & _
                                        '00\s00\s00\s00\s' & _
                                        '..\s..\s'  & _
                                        '00\s00\s00\s00\s00\s00\s00\s00\s' & _
                                        '.*?(?:00\s)'
Local $asResult = StringRegExp($sText, $sRegExp, 3)
;~ _ArrayDisplay($asResult)

Local $sResult = ""
Local $sRegExp =         _
                                        '(3\d\s3\d\s3\d\s3\d\s3\d\s3\d\s)' & _
                                        '00\s00\s00\s' & _
                                        '..\s'  & _
                                        '00\s00\s00\s00\s' & _
                                        '..\s..\s'  & _
                                        '00\s00\s00\s00\s00\s00\s00\s00\s' & _
                                        '(.*?)(?:00\s)'
For $i = 0 To UBound($asResult) - 1 Step 1
        $asTemp   = StringRegExp($asResult[$i], $sRegExp, 3)
        $sResult &= BinaryToString('0x' & StringStripWS($asTemp[0], 8)) &@TAB& BinaryToString('0x' & StringStripWS($asTemp[1], 8)) & @CRLF
Next
;~ ClipPut($sResult)

If FileExists("Result.txt") Then FileDelete("Result.txt")
FileWrite("Result.txt", $sResult)
;~ MsgBox(4096, "", TimerDiff($iTime))

If $SearchKey Then
        $asResult = StringRegExp($sResult, '.*' & $SearchKey & '.*?\v', 3)
        If @error Then
                MsgBox(0, "查询结果", "关键字: " & "$SearchKey" &@CRLF& "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& "没找到相似的结果!")
        Else
                $sResult  = ""
                For $i = 0 To UBound($asResult) - 1 Step 1
                        $sResult &= $asResult[$i] & @CRLF
                Next
                MsgBox(0, "查询结果", "关键字: " & $SearchKey &@CRLF& "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& $sResult)
        EndIf
EndIf
Exit
大概1500ms

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2011-5-2 14:09:39 | 显示全部楼层
本帖最后由 easefull 于 2011-5-3 11:21 编辑

效率测试,从读入减肥文件到得出查询结果的时间:
;version: 0.1.1 Beta
#include <Array.au3>
Local $oFile, $sText
$oFile = FileOpen("shex.tnf", 16)
$sText = FileRead($oFile)
$sText = StringRegExpReplace($sText, '(.{2})',  '\1' & " ")
FileClose($oFile)

Local $SearchKey = InputBox("查询", "请输入股票名称或代码")
Local $iTime = TimerInit()
Local $sRegExp  =         _
                                        '3\d\s3\d\s3\d\s3\d\s3\d\s3\d\s' & _
                                        '00\s00\s00\s' & _
                                        '..\s'  & _
                                        '00\s00\s00\s00\s' & _
                                        '..\s..\s'  & _
                                        '00\s00\s00\s00\s00\s00\s00\s00\s' & _
                                        '.*?(?:00\s)'
Local $asResult = StringRegExp($sText, $sRegExp, 3)
;~ _ArrayDisplay($asResult)

Local $sResult = ""
Local $sRegExp =         _
                                        '(3\d\s3\d\s3\d\s3\d\s3\d\s3\d\s)' & _
                                        '00\s00\s00\s' & _
                                        '..\s'  & _
                                        '00\s00\s00\s00\s' & _
                                        '..\s..\s'  & _
                                        '00\s00\s00\s00\s00\s00\s00\s00\s' & _
                                        '(.*?)(?:00\s)'
For $i = 0 To UBound($asResult) - 1 Step 1
        $asTemp   = StringRegExp($asResult[$i], $sRegExp, 3)
        $sResult &= BinaryToString('0x' & StringStripWS($asTemp[0], 8)) &@TAB& BinaryToString('0x' & StringStripWS($asTemp[1], 8)) & @CRLF
Next
;~ ClipPut($sResult)

If FileExists("Result.txt") Then FileDelete("Result.txt")
FileWrite("Result.txt", $sResult)
;~ MsgBox(4096, "", TimerDiff($iTime))

$iTime = TimerInit()
If $SearchKey Then
        $asResult = StringRegExp(FileRead("Result.txt"), '.*' & $SearchKey & '.*?\v', 3)
        If @error Then
                MsgBox(0, "查询结果", "关键字: " & "$SearchKey" &@CRLF& "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& "没找到相似的结果!")
        Else
                $sResult  = ""
                For $i = 0 To UBound($asResult) - 1 Step 1
                        $sResult &= $asResult[$i] & @CRLF
                Next
                MsgBox(0, "查询结果", "关键字: " & $SearchKey &@CRLF& "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& $sResult)
        EndIf
EndIf
Exit
这个时间对比41楼的1500ms,这就说明减肥文件也有存在的必要性.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2011-5-2 14:30:35 | 显示全部楼层
本帖最后由 love5173 于 2011-5-2 14:39 编辑

回复 42# easefull
你的时间点取错了,速度应该是1500ms
不过你的处理方式很特别,能讲讲吗
#include <Array.au3>
Local $oFile, $sText
$iTime = TimerInit()
$oFile = FileOpen("shex.tnf", 16)
$sText = FileRead($oFile)
$sText = StringRegExpReplace($sText, '(.{2})',  '\1' & " ")
FileClose($oFile)

Local $SearchKey = "000001"
;Local $iTime = TimerInit()
Local $sRegExp  =         _
                                        '3\d\s3\d\s3\d\s3\d\s3\d\s3\d\s' & _
                                        '00\s00\s00\s' & _
                                        '..\s'  & _
                                        '00\s00\s00\s00\s' & _
                                        '..\s..\s'  & _
                                        '00\s00\s00\s00\s00\s00\s00\s00\s' & _
                                        '.*?(?:00\s)'
Local $asResult = StringRegExp($sText, $sRegExp, 3)
;~ _ArrayDisplay($asResult)

Local $sResult = ""
Local $sRegExp =         _
                                        '(3\d\s3\d\s3\d\s3\d\s3\d\s3\d\s)' & _
                                        '00\s00\s00\s' & _
                                        '..\s'  & _
                                        '00\s00\s00\s00\s' & _
                                        '..\s..\s'  & _
                                        '00\s00\s00\s00\s00\s00\s00\s00\s' & _
                                        '(.*?)(?:00\s)'
                                                                                
For $i = 0 To UBound($asResult) - 1 Step 1
        $asTemp   = StringRegExp($asResult[$i], $sRegExp, 3)
        $sResult &= BinaryToString('0x' & StringStripWS($asTemp[0], 8)) &@TAB& BinaryToString('0x' & StringStripWS($asTemp[1], 8)) & @CRLF
Next
;~ ClipPut($sResult)
;MsgBox(0,"",$sResult)
If FileExists("Result.txt") Then FileDelete("Result.txt")
FileWrite("Result.txt", $sResult)
;~ MsgBox(4096, "", TimerDiff($iTime))


If $SearchKey Then
        $asResult = StringRegExp(FileRead("Result.txt"), '.*' & $SearchKey & '.*?\v', 3)
        If @error Then
                MsgBox(0, "查询结果", "关键字: " & "$SearchKey" &@CRLF& "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& "没找到相似的结果!")
        Else
                $sResult  = ""
                For $i = 0 To UBound($asResult) - 1 Step 1
                        $sResult &= $asResult[$i] & @CRLF
                Next
                MsgBox(0, "查询结果", "关键字: " & $SearchKey &@CRLF& "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& $sResult)
        EndIf
EndIf
Exit

这个才是你的程序的用时
发表于 2011-5-2 14:57:01 | 显示全部楼层
本帖最后由 easefull 于 2011-5-2 15:03 编辑

回复 43# love5173

呃,确实是时间点取错了.
41楼的时间点确实是弄错了.
42楼的时间点没错,那个是计算使用减肥文件的时间,前面大段代码都只是为了生成减肥文件.

原理是,读二进制文件,然后根据原文件的格式匹配二进制字符串.
接着再把结果一个个还原成ANSI格式的字符串
下来是保存结果
最后面才是从结果文件搜索关键字,然后给出整行结果.
发表于 2011-5-2 14:59:46 | 显示全部楼层
本帖最后由 easefull 于 2011-5-3 14:09 编辑

2011-05-03 v0.3.1 Beta        代码见本楼                改进冗余的正则
2011-05-03 v0.3.0 Beta        代码已删除                修正无法获取8字头股票的Bug(感谢3mile指出此Bug)
2011-05-02 v0.2.0 Beta        代码已删除                采用直接匹配,去除冗余的每字节间隔的步骤.
2011-05-02 v0.1.2 Beta        代码在41楼                修正时间点取错的Bug(感谢love5173指出此Bug)
2011-05-02 v0.1.1 Beta        代码在42楼                添加TimerDiff测试效率.
2011-05-01 v0.1.0 Beta        代码在28楼                完成二进制匹配方式的第一个版本
;version: v0.3.1 Beta
#include <Array.au3>
Local $SearchKey = InputBox("查询", "请输入股票名称或代码")
Local $iTime = TimerInit()

Local $oFile, $sText
$oFile = FileOpen("SNT.txt", 16)
$sText = FileRead($oFile)
FileClose($oFile)

Local $sRegExp  = '3\d3\d3\d3\d3\d3\d' & '0{6}.{2}0{6}.{6}0{16}' & '.*?00'
Local $asResult = StringRegExp($sText, $sRegExp, 3)
;~ _ArrayDisplay($asResult)

Local $sResult = ""
Local $sRegExp = '(3\d3\d3\d3\d3\d3\d)' & '0{6}.{2}0{6}.{6}0{16}' & '(.*?)00'
For $i = 0 To UBound($asResult) - 1 Step 1
        $asTemp = StringRegExp($asResult[$i], $sRegExp, 3)
        If StringLen($asTemp[1])/2 <> Int(StringLen($asTemp[1])/2) Then $asTemp[1] &= "0"
        $sResult &= BinaryToString('0x' & $asTemp[0]) &@TAB& BinaryToString('0x' & $asTemp[1]) & @CRLF
Next
;~ ClipPut($sResult)

;~ If FileExists("Result.txt") Then FileDelete("Result.txt")
;~ FileWrite("Result.txt", $sResult)
;~ MsgBox(4096, "", TimerDiff($iTime))
;~ $iTime = TimerInit()

If $SearchKey Then
        $asResult = StringRegExp($sResult, '.*' & $SearchKey & '.*\v', 3)
        If @error Then
                MsgBox(0, "查询结果", "关键字: " & $SearchKey &@CRLF& "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& "没找到相似的结果!")
        Else
                $sResult  = ""
                For $i = 0 To UBound($asResult) - 1 Step 1
                        $sResult &= $asResult[$i]
                Next
                MsgBox(0, "查询结果", "关键字: " & $SearchKey &@CRLF& "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& $sResult)
        EndIf
Else
        ClipPut($sResult)
        If Not IsArray($asResult) Then
                MsgBox(0, "查询结果", "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& "未发现股票编号记录")
        Else
                MsgBox(0, "查询结果", "用时: " & TimerDiff($iTime) & "毫秒" &@CRLF&@CRLF& "发现: " & UBound($asResult) & " 个股票编号记录")
        EndIf
EndIf
Exit
; version:0.3.0 正则
Local $sRegExp  = '3\d3\d3\d3\d3\d3\d' & '0{6}.{2}0{6,8}.{4,6}0{16}' & '.*?00'

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 1金钱 +10 收起 理由
netbean + 10 非常感谢

查看全部评分

您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-13 22:35 , Processed in 0.093955 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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