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


    的确如此。其实这道题目是我前几天确实遇到过的实际情况,实际样本中,空行只是在段落与段落之间,而在段落中并没有空行。我在出题目时,也就没有考虑到段落中也出现空行的情况。感谢你的建议,的确应该兼顾这种情况,那么我上面的解就完全错了,明天我改一下。今天晚上还要出去,不能上网了。
页: 1 [2] 3 4 5
查看完整版本: 练习003 - 顺序排列文本中的无序内容