llztt
发表于 2010-1-17 00:14:53
$begin=TimerInit()
$fc=FileRead("a.txt")
$array=StringRegExp($fc,"\r\n\r\n\:([\s\S]+?)(?=\r\n\r\n\:)",3)
Dim $thestr
for $i = 0 to UBound($array) - 1
$thestr[$i]=$array[$i]
Next
$array=StringRegExp($fc,"\A\:([\s\S]+?)\r\n\r\n\:[\s\S]*\z",1)
If Not @error Then
Local $an=UBound($thestr)
ReDim $thestr[$an+1]
$thestr[$an]=$array
EndIf
$array=StringRegExp($fc,"(?:[\s\S]+?\r\n\r\n\:)*([\s\S]*)\z",1)
If Not @error Then
Local $an=UBound($thestr)
ReDim $thestr[$an+1]
$thestr[$an]=$array
EndIf
For $i=0 To UBound($thestr)-1
For $j=$i To 0 Step -1
If $j>0 And StringLeft($thestr[$j],1)<StringLeft($thestr[$j-1],1) Then
$tmpval=$thestr[$j]
$thestr[$j]=$thestr[$j-1]
$thestr[$j-1]=$tmpval
EndIf
Next
Next
$thelast=":"&$thestr
For $i=1 To UBound($thestr)-1
$thelast=$thelast&@CRLF&@CRLF&":"&$thestr[$i]
Next
;ConsoleWrite($thelast&@CRLF)
FileDelete("a.txt")
FileWrite("a.txt",$thelast)
$diff=TimerDiff($begin)
MsgBox(0,"",$diff&"毫秒")如果保证文件格式规范,可以不用UBOUND,再精简一点,但代码还是感觉冗余啊,。。唉,还是学习学习前面几位耗了。。
llztt
发表于 2010-1-17 00:23:12
看到Afan的代码了,真是精炼啊,呵呵,为了重排序,我可想了半天,原来可以这么简单。。呵呵
不过要求中:2、每个段落中有m条内容(m>0),每行内容的第一个字符总是不为冒号:。
并不保证:冒号不出现在非第一字符,譬如出现在内容之中呢?我测试了一下,显示失败了,Afan可以再改进一下,呵呵
pusofalse
发表于 2010-1-17 00:23:14
本帖最后由 pusofalse 于 2010-1-17 00:25 编辑
FileDelete、FileWrite这两句降低了不少效率,其实也不必重写文件,直接Msgbox输出即可。输出的结果有点问题,:true在:test之前,用以下样本测试的::true
true??
assign!
:false
false??
:loop
L$***,G$***
:M$
M$###,M-obj
:test
^^~!!%%^^
false??
llztt
发表于 2010-1-17 00:31:59
本帖最后由 llztt 于 2010-1-17 01:08 编辑
恩,是有着问题,我自以为是只排第一字符就够了呢,理解失误了,呵呵
貌似直接字符串之间用大于小于比较就可以了,AFAN的好像也是这样做了
因为分隔符比较规律,所以,感觉用stringsplit更简洁些如下:$begin=TimerInit()
$fc=FileRead("a.txt")
Dim $strNew
$thestr=StringSplit(StringRight($fc,StringLen($fc)-1),Chr(13)&Chr(10)&":",1)
For $i=1 To $thestr
For $j=$i To 1 Step -1
If $j>1 And $thestr[$j]<$thestr[$j-1] Then
$tmpval=$thestr[$j]
$thestr[$j]=$thestr[$j-1]
$thestr[$j-1]=$tmpval
EndIf
Next
Next
$thelast=":"&$thestr
For $i=2 To $thestr
$thelast=$thelast&@CRLF&@CRLF&":"&$thestr[$i]
Next
$diff=TimerDiff($begin)
MsgBox(0, '完成耗时(s):' & TimerDiff($begin) / 1000, $thelast)数组临界判断没加。。。呵呵,菜偷差不多了,得睡觉去啦,pusofalse大大,还不睡哈
afan
发表于 2010-1-17 01:08:29
看到Afan的代码了,真是精炼啊,呵呵,为了重排序,我可想了半天,原来可以这么简单。。呵呵
不过要求中 ...
llztt 发表于 2010-1-17 00:23 http://www.autoitx.com/images/common/back.gif
谢谢提醒,一会我修改下~
pusofalse
发表于 2010-1-17 01:56:15
回复 19# llztt
果真强大,如果能够去掉函数调用就完美至极了。
不调用任何函数,这样做带来的后果是代码臃肿,或者还有可能是效率低下(?)。
测试以下代码就能体会到“合理使用语句、运算符”和“调用函数”之间的效率差别了:Dim $dTimer1 = TimerInit(), $iCount1
For $i = 1 To 1000000
$iCount1 += 1
Next
Msgbox(0, '', TimerDiff($dTimer1))
Dim $dTimer2 = TimerInit(), $iCount2
For $i = 1 To 1000000
$iCount2 = $iCount2 + 1
Next
Msgbox(0, '', TimerDiff($dTimer2))
Dim $dTimer3 = TimerInit(), $iCount3
For $i = 1 To 1000000
$iCount3 += _Test()
Next
Msgbox(0, '', TimerDiff($dTimer3))
Func _Test()
Return 1 ; 什么也不做,立即返回。
EndFunc当然上面的3段代码是没有任何意义的,只是能够非常清楚地表明其间的效率差别。
结论:
1、程序效率至上(这个与个人性格有关 - -|||)。
2、合理调用函数,能够合理地使用语句完成的指令,尽量不调用函数。当然这也要看个人喜好。
3、用最合适的代码,做最合适的事情。
lchl0588
发表于 2010-1-17 08:36:54
#19
试问:如果用":a~:z"判断顺序 是否可行!!
#21
1、程序效率至上(这个与个人性格有关 - -|||)。
2、合理调用函数,能够合理地使用语句完成的指令,尽量不调用函数。当然这也要看个人喜好。
3、用最合适的代码,做最合适的事情。
不同意:
1、多半跟个人的AU3水平有关(其实出题的那一分钟,偶就有了思路,因水平有限,无法编辑出)
23出题有条件是最好的,因为有限制,才能展出个人的水平!
llztt
发表于 2010-1-17 09:25:05
本帖最后由 llztt 于 2010-1-17 20:43 编辑
那个重排顺序上,还不能省事呢,目前我只有重排数组的办法了
bing614
发表于 2010-1-17 12:33:45
学习下。.....
lxz
发表于 2010-1-17 12:38:55
学习下。.....
C.L
发表于 2010-1-17 14:40:17
本帖最后由 C.L 于 2010-1-17 14:45 编辑
有空了重做一次,11楼的代码太臃肿了,优化了一下代码,去掉了二维数组,循环减少了两个,还是只用运算符和语句
$timestart = TimerInit ()
Dim $atemp ,$temp,$lines
$i=1
$m=4
While 1
$sLine = FileReadLine ("a.txt",$i)
$atemp[$m] = $lines&@CRLF
If @error = -1 Then
For $i = 0 To 4
If $temp < $atemp[$i] Then
$temp&= $atemp[$i]
Else
$temp = $atemp[$i] & $temp
EndIf
Next
ExitLoop
EndIf
If $sLine <> "" Then
$lines &= $sLine&@CRLF
Else
$atemp[$m] = $lines&@CRLF
$lines = ""
$m -= 1
EndIf
$i += 1
WEnd
MsgBox (0,"运行时间:"&TimerDiff ($timestart)&"毫秒",$temp)
afan
发表于 2010-1-17 15:48:30
抽空再向各位前辈学习~~
pusofalse
发表于 2010-1-17 17:16:35
本帖最后由 pusofalse 于 2010-1-17 17:19 编辑
感谢诸位参与。以下是我的解,效率不怎样,问题出在了FileReadLine("a.txt", ...)这一句,测试打开文件句柄之后再读取,速度会快很多。I/O操作果真费时。一次读取全部,再用StringRegExp切割,速度会增加数倍,但不知在不使用Ubound函数的情况下,如何得到数组的元素数量。Local $dTimer = TimerInit(), $iIndex, $hFile
Local $sLine, $aVar, $aVar1, $sResult, $iLineIndex = 0, $iFlags = 1
;$hFile = FileOpen("a.txt", 0)
While 1
$iLineIndex += 1
$sLine = FileReadLine("a.txt", $iLineIndex)
If @error Then ExitLoop
If $sLine = "" Then
$iFlags = 1
ContinueLoop
EndIf
If $iFlags Then
$aVar += 1
Redim $aVar[$aVar + 1]
$aVar[$aVar] = $sLine
$iFlags = 0
Else
$aVar[$aVar] &= $sLine & @CRLF
EndIf
WEnd
;FileClose($hFile)
$aVar1 = $aVar
For $i = 1 To $aVar1
$iIndex = 1
For $j = 1 To $aVar1
If $aVar1[$i] > $aVar1[$j] Then $iIndex += 1
Next
$aVar[$iIndex] = $aVar1[$i]
$aVar[$iIndex] = $aVar1[$i]
Next
For $i = 1 To $aVar
$sResult &= $aVar[$i] & @CRLF & $aVar[$i] & @CRLF
Next
Msgbox(0, TimerDiff($dTimer) / 1000, $sResult)
llztt
发表于 2010-1-17 17:31:39
哈哈,一直等楼主的解,终于看到了,呵呵
不过可能我太钻牛角尖了,对条件的理解有些多了“4、段落与段落之间,总是有一空行连接。”,这并不约束段落中出现空行吧,感觉描述的最终理解为:空行+冒号开头的次行,这是区分该文件段落的分界符。。
如果以上理解通过的话,大大的解就得再改改了。。
pusofalse
发表于 2010-1-17 17:52:01
回复 29# llztt
的确如此。其实这道题目是我前几天确实遇到过的实际情况,实际样本中,空行只是在段落与段落之间,而在段落中并没有空行。我在出题目时,也就没有考虑到段落中也出现空行的情况。感谢你的建议,的确应该兼顾这种情况,那么我上面的解就完全错了,明天我改一下。今天晚上还要出去,不能上网了。