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