在日常代碼編制時,許多人會忽略一些最基本的算法,導(dǎo)致代碼冗余,思路不清楚。我曾經(jīng)至少兩次在CSDN里遇到這類問題:我想在頁面的右邊顯示一個列表,列表長度為20,新加入一個用戶后,顯示在列表開頭,再加入的用戶,顯示在這個用戶的下邊,當(dāng)用戶數(shù)量超過20后,擠掉最前面的那一位,第二位加入的用戶成了第一位,依次循環(huán),保證列表最多顯示20位用戶。當(dāng)然,實(shí)際問題可能與此有些出入,比如Coder是想顯示網(wǎng)友們最近選擇的歌曲列表,但實(shí)際意思差不多。
面對這個問題,大多數(shù)朋友會想到使用數(shù)據(jù)。其實(shí),這完全是一個隊(duì)列,只不過,這個隊(duì)列可以循環(huán)使用,在加入隊(duì)列元素時,如果超過長度,會自動擠掉最先加入的。如果能夠用代碼直接實(shí)現(xiàn),為什么要用數(shù)據(jù)庫呢?考慮一下,為了提高網(wǎng)站性能,我們絞盡腦汁,卻往往因?yàn)樗悸返钠?,?dǎo)致性能降低。
那么,在VB中如何實(shí)現(xiàn)可循環(huán)的隊(duì)列呢?
為此,我編寫了一個循環(huán)隊(duì)列類,以滿足上述需要,同時為了方便在HTML、ASP、WSH的VBScript腳本語言環(huán)境中使用,該類未聲明任何數(shù)據(jù)類型。
首先看一下該循環(huán)隊(duì)列類的源代碼:
'* ************************************************************** *
'* 程序名稱:Queue.cls
'* 程序功能:一個VB循環(huán)隊(duì)列類
'* 作者:lyserver
'* 聯(lián)系方式:http://blog.csdn.net/lyserver
'* ************************************************************** *
'Class Queue '在ASP、WSH、HTML的VBScript腳本中使用時需加此句
Dim m_Queue() '隊(duì)列
Dim m_RetQueue() '隊(duì)列返回值
Dim m_ReadIndex '列首偏移索引
Dim m_WriteIndex '元素插入偏移索引
Dim m_MaxLen '隊(duì)列最大尺寸
Private Sub Class_Initialize()
m_ReadIndex = 0
m_WriteIndex = 0
m_MaxLen = 20 '隊(duì)列默認(rèn)大小為20
ReDim m_Queue(m_MaxLen - 1)
End Sub
Private Sub Class_Terminate()
Erase m_Queue
Erase m_RetQueue
End Sub
'獲得隊(duì)列大小
Public Property Get MaxLen()
MaxLen = m_MaxLen
End Property
'設(shè)置隊(duì)列大小
Public Property Let MaxLen(ByVal NewValue)
If NewValue > 0 Then
m_MaxLen = NewValue
ReDim m_Queue(m_MaxLen)
End If
End Property
'插入隊(duì)列元素
Public Sub Insert(ByVal v)
If m_WriteIndex = m_MaxLen Then '隊(duì)列已滿,擠掉最先插入的元素
m_WriteIndex = 0
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End If
m_Queue(m_WriteIndex) = v
m_WriteIndex = m_WriteIndex + 1
End Sub
'刪除隊(duì)列元素(按隊(duì)列原則,實(shí)際上是刪除最先插入的元素)
Public Sub Delete()
Dim vTemp
m_Queue(m_ReadIndex) = vTemp '將此變量置為未初始化
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End Sub
'清空隊(duì)列
Public Sub Clear()
ReDim m_Queue(m_MaxLen)
m_WriteIndex = 0
m_ReadIndex = 0
End Sub
'獲得隊(duì)列數(shù)組
Public Property Get GetQueue()
Dim i, n
n = 0
ReDim m_RetQueue(m_MaxLen)
For i = m_ReadIndex To m_MaxLen - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
n = n + 1
Next
For i = 0 To m_ReadIndex - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
n = n + 1
Next
GetQueue = m_RetQueue
End Property
'End Class '在ASP、WSH、HTML的VBScript腳本中使用時需加此句
'* ************************************************************** *
'* 程序名稱:Queue.cls
'* 程序功能:一個VB循環(huán)隊(duì)列類
'* 作者:lyserver
'* 聯(lián)系方式:http://blog.csdn.net/lyserver
'* ************************************************************** *
'Class Queue '在ASP、WSH、HTML的VBScript腳本中使用時需加此句
Dim m_Queue() '隊(duì)列
Dim m_RetQueue() '隊(duì)列返回值
Dim m_ReadIndex '列首偏移索引
Dim m_WriteIndex '元素插入偏移索引
Dim m_MaxLen '隊(duì)列最大尺寸
Private Sub Class_Initialize()
m_ReadIndex = 0
m_WriteIndex = 0
m_MaxLen = 20 '隊(duì)列默認(rèn)大小為20
ReDim m_Queue(m_MaxLen - 1)
End Sub
Private Sub Class_Terminate()
Erase m_Queue
Erase m_RetQueue
End Sub
'獲得隊(duì)列大小
Public Property Get MaxLen()
MaxLen = m_MaxLen
End Property
'設(shè)置隊(duì)列大小
Public Property Let MaxLen(ByVal NewValue)
If NewValue > 0 Then
m_MaxLen = NewValue
ReDim m_Queue(m_MaxLen)
End If
End Property
'插入隊(duì)列元素
Public Sub Insert(ByVal v)
If m_WriteIndex = m_MaxLen Then '隊(duì)列已滿,擠掉最先插入的元素
m_WriteIndex = 0
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End If
m_Queue(m_WriteIndex) = v
m_WriteIndex = m_WriteIndex + 1
End Sub
'刪除隊(duì)列元素(按隊(duì)列原則,實(shí)際上是刪除最先插入的元素)
Public Sub Delete()
Dim vTemp
m_Queue(m_ReadIndex) = vTemp '將此變量置為未初始化
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End Sub
'清空隊(duì)列
Public Sub Clear()
ReDim m_Queue(m_MaxLen)
m_WriteIndex = 0
m_ReadIndex = 0
End Sub
'獲得隊(duì)列數(shù)組
Public Property Get GetQueue()
Dim i, n
n = 0
ReDim m_RetQueue(m_MaxLen)
For i = m_ReadIndex To m_MaxLen - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
n = n + 1
Next
For i = 0 To m_ReadIndex - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
n = n + 1
Next
GetQueue = m_RetQueue
End Property
'End Class '在ASP、WSH、HTML的VBScript腳本中使用時需加此句
然后,我們再來看一下在VB中如何使用此類:
Sub main()
Dim objQueue
Dim i, nLen
Set objQueue = New Queue
'將隊(duì)列長度置為5
nLen = 5
objQueue.MaxLen = nLen
'向隊(duì)列插入元素(不超過隊(duì)列長度)
For i = 1 To nLen
objQueue.Insert i
Next
'顯示結(jié)果
DisplayQueue objQueue
'清空隊(duì)列后重新插入元素(超過隊(duì)列長度)
objQueue.Clear
For i = 1 To nLen + 1
objQueue.Insert i
Next
'顯示結(jié)果
DisplayQueue objQueue
'刪除隊(duì)列元素
objQueue.Delete
'顯示結(jié)果
DisplayQueue objQueue
End Sub
Private Sub DisplayQueue(qu)
Dim v(), i
v = qu.GetQueue
For i = 0 To qu.MaxLen - 1
If IsEmpty(v(i)) Then Exit For
Debug.Print "第" & i + 1 & "個元素的值:", v(i)
Next
Debug.Print "------顯示完畢------"
End Sub
Sub main()
Dim objQueue
Dim i, nLen
Set objQueue = New Queue
'將隊(duì)列長度置為5
nLen = 5
objQueue.MaxLen = nLen
'向隊(duì)列插入元素(不超過隊(duì)列長度)
For i = 1 To nLen
objQueue.Insert i
Next
'顯示結(jié)果
DisplayQueue objQueue
'清空隊(duì)列后重新插入元素(超過隊(duì)列長度)
objQueue.Clear
For i = 1 To nLen + 1
objQueue.Insert i
Next
'顯示結(jié)果
DisplayQueue objQueue
'刪除隊(duì)列元素
objQueue.Delete
'顯示結(jié)果
DisplayQueue objQueue
End Sub
Private Sub DisplayQueue(qu)
Dim v(), i
v = qu.GetQueue
For i = 0 To qu.MaxLen - 1
If IsEmpty(v(i)) Then Exit For
Debug.Print "第" & i + 1 & "個元素的值:", v(i)
Next
Debug.Print "------顯示完畢------"
End Sub
看過了VB使用方法后,我們再來看一下在HTML的VBScript腳本中如何使用,需要注意的是,要想測試結(jié)果,必須將以下代碼復(fù)制到記事本后另存為擴(kuò)展名為html或htm的文件,然后使用IE打開,對于類代碼,讀者也可以單獨(dú)取出來存為vbs文件,然后html里包含它就可以了。至于ASP,思路與此完全一樣。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>新建網(wǎng)頁 1</title>
</head>
<body>
</body>
</html>
<mce:script language=vbscript><!--
Option Explicit
'* ************************************************************** *
'* 程序名稱:Queue.cls
'* 程序功能:一個VB循環(huán)隊(duì)列類
'* 作者:lyserver
'* 聯(lián)系方式:http://blog.csdn.net/lyserver
'* ************************************************************** *
Class Queue
Dim m_Queue() '隊(duì)列
Dim m_RetQueue() '隊(duì)列返回值
Dim m_ReadIndex '列首偏移索引
Dim m_WriteIndex '元素插入偏移索引
Dim m_MaxLen '隊(duì)列最大尺寸
Private Sub Class_Initialize()
m_ReadIndex = 0
m_WriteIndex = 0
m_MaxLen = 20 '隊(duì)列默認(rèn)大小為20
ReDim m_Queue(m_MaxLen - 1)
End Sub
Private Sub Class_Terminate()
Erase m_Queue
Erase m_RetQueue
End Sub
'獲得隊(duì)列大小
Public Property Get MaxLen()
MaxLen = m_MaxLen
End Property
'設(shè)置隊(duì)列大小
Public Property Let MaxLen(ByVal NewValue)
If NewValue > 0 Then
m_MaxLen = NewValue
ReDim m_Queue(m_MaxLen)
End If
End Property
'插入隊(duì)列元素
Public Sub Insert(ByVal v)
If m_WriteIndex = m_MaxLen Then '隊(duì)列已滿,擠掉最先插入的元素
m_WriteIndex = 0
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End If
m_Queue(m_WriteIndex) = v
m_WriteIndexm_WriteIndex = m_WriteIndex + 1
End Sub
'刪除隊(duì)列元素(按隊(duì)列原則,實(shí)際上是刪除最先插入的元素)
Public Sub Delete()
Dim vTemp
m_Queue(m_ReadIndex) = vTemp '將此變量置為未初始化
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End Sub
'清空隊(duì)列
Public Sub Clear()
ReDim m_Queue(m_MaxLen)
m_WriteIndex = 0
m_ReadIndex = 0
End Sub
'獲得隊(duì)列數(shù)組
Public Property Get GetQueue()
Dim i, n
n = 0
ReDim m_RetQueue(m_MaxLen)
For i = m_ReadIndex To m_MaxLen - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
nn = n + 1
Next
For i = 0 To m_ReadIndex - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
nn = n + 1
Next
GetQueue = m_RetQueue
End Property
End Class
Sub window_onload
Dim objQueue
Dim i, nLen
Set objQueue=New Queue
'將隊(duì)列長度置為5
nLen = 5
objQueue.MaxLen = nLen
'向隊(duì)列插入元素(不超過隊(duì)列長度)
For i = 1 To nLen
objQueue.Insert i
Next
'顯示結(jié)果
DisplayQueue objQueue
'清空隊(duì)列后重新插入元素(超過隊(duì)列長度)
objQueue.Clear
For i = 1 To nLen + 1
objQueue.Insert i
Next
'顯示結(jié)果
DisplayQueue objQueue
'刪除隊(duì)列元素
objQueue.Delete
'顯示結(jié)果
DisplayQueue objQueue
End Sub
Sub DisplayQueue(qu)
Dim v,i
v = qu.GetQueue
For i = 0 To qu.MaxLen - 1
If IsEmpty(v(i)) Then Exit For
document.write "第" & i + 1 & "個元素的值:" & v(i) & "<br>"
Next
document.write "------顯示完畢------<br>"
End Sub
// --></mce:script>
該文章在 2013/11/28 11:48:35 編輯過