【pbvb大杂烩】一段狠long狠long的故事,和一个算法
这事儿要从我读高中时说起。。。那年 人们害怕而又迫切地等待着玛雅传说中的末日的来临。那年 略显青涩的我激动万分地踏进了高中高二的大门。那年 崭新发亮的17寸宏碁显示器来到了一个中学生破旧的desk top 上。那年 。。。。咳咳 年够了。。对,当时刚接触1年vb的我在写一款字频计算程序,字频计算嘛,“abccde”一串字符,其中 a几个 b几个?好了我写了如下代码(当时的source code丢掉了,因而对我的移动硬盘的考古工作无法进行,我就大概写一些,见笑了:))Private Sub Command1_Click()
Dim atime As Integer
Dim btime As Integer
Dim ctime As Integer
Dim dtime As Integer
Dim etime As Integer
'......以下省略21个dim......
Dim i As Integer
For i = 1 To Len(text1.Text)
Dim s As String
s = Mid(text1.Text, i, 1)
If s = "a" Then
atime = atime + 1
End If
'......以下省略25个if闭包......
Next
MsgBox "亲,字符a出现了:" & atime & "次.出现频率为:" & atime / Len(text1.Text)
MsgBox "亲,字符b出现了:" & btime & "次.出现频率为:" & atime / Len(text1.Text)
'........以下省略24个msgbox...........
End Sub
观看过我的代码的你,一定感慨万千。。。。(啊,老C啊,你TM真傻X啊¥#@%¥#W……%(-。-;)¥&……)
嗯!不准嘲笑我的智商,起码我是一个勤奋的程序员。
好的,过了大概几个月,我又对“字频计算 v0.01进行了改进”:
Private Sub Command1_Click()
Dim alphat(26) As Integer '呵呵,老C的学习能力如同沙耶,别小看我!!!
Dim i As Integer
For i = 1 To Len(text1)
alphat(Asc(id(text1, i, 1)) - 96) = UBound(Split(text1, "a"))
Next
For i = 1 To 26
text2 = text2 & "亲亲,字符a出现了:" & alphat(i) & "次.出现频率为:" & alphat(i) / Len(text1.Text) & vbCrLf
Next
End Sub
亲啊,see see !10行代码 ! 有木有!有木有!
兴奋劲儿马上过去了。。。
卧槽,计算中文字频咋办?!
咋办!什么算法能实现?好啊,又是一顿苦苦搜寻,->《21天精通vb》《vb编程宝典》《金瓶梅》《乱七八糟什么日文,还是图片,你懂的。。》
没找到!!!瞎了呀,肾费了不少,代码却没出来《=嗯嗯,和谐 和谐。
好,开始研究人类咋计算字频。
duang~弄来a4那么大一张白纸,上书“你你你我我我他aabbccX井控X藤兰”开始一个一个找:“你,1个,你,两个,你,三个”
把我数成白痴了也没想出来。。
后来后来后来再后来。我突然有了灵感!!!我数“你”,“你”就进了我的大脑,第二次发现“你”我就搜索大脑,你今天有了么?有了!
那么bingo!你+1,以此类推。。。好了捉摸出这么一套算法,我把它称为计数算法
简而言之就是建立一个数组,在目标字符串内搜索字符,没该字符,“海马体”数组+1,计数+1.好了,老C献上PB算法:
'this is aint vb its pb code!!!!!
#Compile Exe
#Dim All
Macro Const = Macro
Const MAXSIZE = 100
Type ElementType
strAs WString * 1
iCtr As Integer
End Type
Global ArrItem() As ElementType
Function PBMain () As Long
Dim ArrItem(MAXSIZE) As ElementType
Local i, j As Integer
Local strAs WString
Local s As WString
str = "你你我我他他他aaaaaabc"
For i = 0 To MAXSIZE
ArrItem(i).str = Chr$(0)
Next
For i = 1 To Len(str)
ItemExists(Mid$(str, i, 1))
Next
j = 0: s = ""
While ArrItem(j).str <> Chr$(0) And j <= MAXSIZE
MsgBox ArrItem(j).str & ":" & Str$(ArrItem(j).iCtr)
j = j + 1
Loop
End Function
Sub ItemExists(ByVal it As WString)
Local i As Integer
While ArrItem(i).str <> Chr$(0) And i <= MAXSIZE
If it = ArrItem(i).str Then
ArrItem(i).iCtr = ArrItem(i).iCtr + 1
Exit Sub
End If
i = i + 1
Wend
For i = 0 To MAXSIZE
If ArrItem(i).str = Chr$(0) Then
ArrItem(i).str = it
ArrItem(i).iCtr = 1
Exit For
End If
Next
End Sub
嗯,又要和大家说再见了,那么老C会讲悲剧嘛?当然不会,皆大欢喜大结局:老C的字频计算上头条:
最后祝你。。。。。学习快乐。。。再见
此贴略水 版主鼠下留情。。
本帖最后由 cyycoish 于 2015-3-9 21:41 编辑
@0xAA55 @美俪女神 @元始天尊 {:soso_e127:}你居然说你能超越沙耶……
alphat(Asc(id(text1, i, 1)) - 96) = UBound(Split(text1, "a"))
这句!!呃好没节操啊!
另外你的字频计算居然上头条!哎果然百度贴吧这种黑暗的领域才是营养丰富的地方虽然确实没啥营养就是了。 本帖最后由 元始天尊 于 2015-3-9 22:08 编辑
看不懂vb,不错计数从算法角度来说没有难度
对于多字节码,由于码元大小不等,因此需要先GetNextCharacter ,然后返回的值作为索引++。而这一步需要做些智能处理
因此优化建议是,采用unicode码,这种码是2字节的,建立索引数组为65536即可,按2字节取码即可,效率应该达到极限 元始天尊 发表于 2015-3-9 22:03
看不懂vb,不错计数从算法角度来说没有难度
对于多字节码,由于码元大小不等,因此需要先GetNextCharacter...
事实上VB的String内部就是用UNICODE编码的,而用户在调用API之类的时候,VB会悄悄地将字符串转换为多字节然后调用,返回的字符串再转换回UNICODE,而为了优化又加入了StrPtr等玩意儿= = 本帖最后由 元始天尊 于 2015-3-9 22:18 编辑
0xAA55 发表于 2015-3-9 22:11
事实上VB的String内部就是用UNICODE编码的,而用户在调用API之类的时候,VB会悄悄地将字符串转换为多字节 ...
看下面写了一堆,我还以为是取ascii码,如果是unicode,就不需要麻烦的判断了,因为索引一定是0~65535的,可能4行就搞定了
int index={0};
WCHAR ptr[]=L"lichao";
for(.....)
{
index]++;
} 元始天尊 发表于 2015-3-9 22:17
看下面写了一堆,我还以为是取ascii码,如果是unicode,就不需要麻烦的判断了,因为索引一定是0~65535的 ...
呃,C语言这种可以写成一行的就算了= =
页:
[1]