练习001 - 计算字符串长度
本帖最后由 pusofalse 于 2010-2-26 23:38 编辑以后会陆续地不定期出一些题目给新手做,当然老鸟也可以出手,但请先给新手发挥的空间。
001 - 计算字符串长度。
出题目的:“表驱动法”的初步认识。
题解:在InputBox中,用户输入不定长度的任意字符串,编程输出其长度(注,此处1个全角字符的长度同为1)。
要求:
此题中禁止使用的内置函数、API函数:
ObjCreate
ObjGet
StringSplit
StringRegExp
StringLen
strlen
lstrlenA
lstrlenW
使用纯AU3编写,禁止调用其他语言(如VBS、JAVA等)。
加分:视思路加分,10-60分不等。
拓展:
在此基础上加深难度,除上述不能使用的函数之外,再禁止使用If ... EndIf语句。
相关参考:
http://www.google.cn/search?hl=zh-CN&source=hp&q=%E8%A1%A8%E9%A9%B1%E5%8A%A8%E6%B3%95&aq=0&oq=%E8%A1%A8%E9%A9%B1%E5%8A%A8
-------------------------------------------------------------------------------------
至此,诸位都有了精彩的代码,总结如下:
1、临时文件法:将字符串写入文件之后,再读取文件大小。又,此题中1个中文字符的长度同为1,但是大小却是2个字节,所以必须用正则将中文字符替换为单字节字符。此法具体见4#代码。
2、逐字符判断法:从左向右依次截取一个字符,并判断是否为空,同时记录截取的次数。直到截取到空值,输出记录次数。此法是目前应用最多的方法,但在效率上会存在问题。具体见5#、8#、10#、13#。
3、变量转化法:先将字符串转为2进制,从左向右依次截取2个字节,判断字节的低位是否为00,为00则基本确定为半角字符,否则为全角。并同时记录次数。直到循环截取完毕。具体见7#。
4、2分法:一次按2个字符进行截取,同时记录截取次数,直到截取到空值,最后根据截取次数的奇偶输出其长度。具体见12#代码。
5、表驱动法:省去一系列逻辑判断,不必创建数组,通过构造表格的方式输出长度。具体见9#、11#、14#代码。
感谢诸位参与。 要求那几点也真是够苛刻的,暂未想到方法。 同楼上,一点头绪都没有,直觉要用得数组. 本帖最后由 马甲 于 2009-12-19 11:31 编辑
StringRegExpReplace 这个可以用是吧。$Str = InputBox("","")
MsgBox(0,"",getlen($Str))
Func getlen($Str)
$file = FileOpen(@ScriptDir&"\len.txt",2)
FileWrite($file,StringRegExpReplace($Str, '[^\x00-\xff]', '0'))
FileClose($file)
Return FileGetSize(@ScriptDir&"\len.txt")
EndFunc$Str = InputBox("","")
MsgBox(0,"",getlen($Str))
Func getlen($Str)
$file = FileOpen(@ScriptDir&"\len.txt",18)
FileWrite($file,$Str)
FileClose($file)
Return FileGetSize(@ScriptDir&"\len.txt")
EndFunc 方法应该很多,只是没详细测试,不知道都能用不$Str = InputBox("","")
MsgBox(0,"",getlen($Str))
Func getlen($Str)
$Str = StringReplace($Str," ","0")
$len = 0
While 1
If $Str = "" Then Return $len
$Str = StringTrimLeft($Str,1)
$len = $len + 1
WEnd
EndFunc 本帖最后由 make2855 于 2009-12-19 12:38 编辑
看错题目了,算了 有用了if,计算输入数据的字节长度
Local $Len=0,$i=1
$String = InputBox("输入数据","输入数据")
$Byte = StringToBinary ($String,2)
$Byte_Len = BinaryLen($Byte)
For $i=3 To $Byte_Len*2 Step 4
If StringMid($Byte,$i+2,2)="00" Then
$Len += 1
Else
$Len += 2
EndIf
Next
MsgBox(0,"输入数据的字节长:",$Len)
本帖最后由 landays 于 2009-12-19 13:14 编辑
$Str = InputBox ("","")
$Fi = 1
For $i = 1 to 100
IF StringTrimLeft ($Str,$i) <> "" Then $Fi = $Fi + 1
IF StringTrimLeft ($Str,$i) = "" Then ExitLoop
Next
MsgBox (64,"",$FI)喔 没注意看清楚不能使用IF 再想想 这个没有用if,使用的版主说的表驱动法
Local $A_Len =
Local $A_Byte = [""]
Local $Len = 0,$n = 1
For $i=1 To 255
$A_Len[$i] = 1
$A_Byte[$i] = Hex($i,2)
Next
$String = InputBox("输入数据","输入数据","输入数据14:“《》.1ddfer23")
$Byte = StringToBinary ($String,2)
$Byte_Len = BinaryLen($Byte)
While $n < $Byte_Len*2
$sSearch = StringMid($Byte,$n+2,2)
For $i= 0 To 255
StringReplace($sSearch, $A_Byte[$i], $A_Len[$i])
$Len += @extended
Next
$n += 2
WEnd
MsgBox(0,"输入数据的字节长:",$Len)
本帖最后由 破帽遮颜 于 2009-12-19 14:07 编辑
喔 没注意看清楚不能使用IF 再想想
landays 发表于 2009-12-19 13:09 http://www.autoitx.com/images/common/back.gif$Str = InputBox("","")
MsgBox(0,"",getlen($Str))
Func getlen($Str)
$len = 0
While True
IF StringTrimLeft ($Str,$len) = '' Then Return $len
$len += 1
IF StringTrimLeft ($Str,$len) <> '' Then $len = $len + 1
WEnd
EndFunc只是帮上面改改~ 9#的代码确实是属于“表驱动”的范畴了,但在执行效率方面有些问题。
表驱动的一个简单例子:$sString = "false"
$sVar = "0123456789" & $sString
Msgbox(0, "长度", StringLeft(StringRight($sVar, 10), 1)) 本帖最后由 fongshun 于 2009-12-20 08:15 编辑
我还没看懂表驱动。先应付下:
(注:此处1个全角字符长度为1。那1个汉字长度亦当做1计算了 :) )
Global $mChar=InputBox("来吧","(注:此处1个全角字符的长度为1"&@CRLF &" 此处1个汉字的长度同为1)")
Global $pos=1,$tempChar
;Global $mLength
While StringMid($mChar,1)==""
MsgBox(0,"0字节","空字符串")
Exit
WEnd
Do
$tempChar=StringMid($mChar,$pos*2)
$pos += 1
Until $tempChar = ""
$pos -=1
$tempChar=StringMid($mChar,$pos*2-1)
Select
Case $tempChar==""
MsgBox(0,"字符串长度:",Int($pos*2-2))
Case $tempChar <> ""
MsgBox(0,"字符串长度:",Int($pos*2-1))
EndSelect
Exit
本帖最后由 C.L 于 2009-12-19 23:36 编辑
哇,看上面的代码,差不多都找不到其他的办法了,不过想了想,我也做了一个练习,应该方法和上面的不同:
$sStr = InputBox("","")
$sStr &= @CR
MsgBox(0,"len",len($sStr))
Func len ($sStr)
Dim $i=0
While StringRight(StringLeft($sStr,$i),1) <> @CR
$i+=1
WEnd
$i-=1
Return $i
EndFunc
本帖最后由 pusofalse 于 2009-12-20 09:58 编辑
Local $sTable, $sVar, $sString, $iLen
For $i = 0 To 65535
$sTable &= Hex($i, 4)
Next
$sString = InputBox("", "")
$sVar = $sTable & $sString & $sString & $sString & $sString
$iLen = StringLeft(StringRight($sVar, 65536 * 4), 4)
Msgbox(0, '', Dec($iLen))$sString = InputBox("", "")
Msgbox(0, '', BinaryLen(StringToBinary($sString, 2)) / 2)
不知何种情况下更适合用“表驱动”?不懂~~~