在日常代碼編製時,許多人會忽略一些最基本的演算法,導致代碼冗餘,思路不清楚。我曾經至少兩次在CSDN裡遇到這類問題:我想在頁面的右邊顯示一個列表,列表長度為20,新加入一個使用者後,顯示在列表開頭,再加入的使用者,顯示在這個使用者的下邊,當使用者數量超過20後,擠掉最前面的那一位,第二位加入的使用者成了第一位,依次迴圈,保證列表最多顯示20位使用者。當然,實際問題可能與此有些出入,比如Coder是想顯示網友們最近選擇的歌曲列表,但實際意思差不多。
面對這個問題,大多數朋友會想到使用資料庫。其實,這完全是一個隊列,只不過,這個隊列可以迴圈使用,在排入佇列元素時,如果超過長度,會自動擠掉最先加入的。如果能夠用代碼直接實現,為什麼要用資料庫呢?考慮一下,為了提高網站效能,我們絞盡腦汁,卻往往因為思路的偏差,導致效能降低。
那麼,在VB中如何?可迴圈的隊列呢?
為此,我編寫了一個迴圈隊列類,以滿足上述需要,同時為了方便在HTML、ASP、WSH的VBScript指令碼語言環境中使用,該類未聲明任何資料類型。
首先看一下該迴圈隊列類的原始碼:
'* ************************************************************** *<br />'* 程式名稱:Queue.cls<br />'* 程式功能:一個VB迴圈隊列類<br />'* 作者:lyserver<br />'* 連絡方式:http://blog.csdn.net/lyserver<br />'* ************************************************************** *<br />Option Explicit</p><p>'Class Queue '在ASP、WSH、HTML的VBScript指令碼中使用時需加此句<br /> Dim m_Queue() '隊列<br /> Dim m_RetQueue() '隊列傳回值<br /> Dim m_HeadOffset '列首位移索引<br /> Dim m_WriteIndex '元素插入位移索引<br /> Dim m_MaxLen '隊列最大尺寸</p><p> Private Sub Class_Initialize()<br /> m_HeadOffset = 0<br /> m_WriteIndex = 0<br /> m_MaxLen = 20 '隊列預設大小為20<br /> ReDim m_Queue(m_MaxLen - 1)<br /> End Sub</p><p> Private Sub Class_Terminate()<br /> Erase m_Queue<br /> Erase m_RetQueue<br /> End Sub</p><p> '獲得隊列大小<br /> Public Property Get MaxLen()<br /> MaxLen = m_MaxLen<br /> End Property</p><p> '設定隊列大小<br /> Public Property Let MaxLen(ByVal NewValue)<br /> If NewValue > 0 Then<br /> m_MaxLen = NewValue<br /> ReDim m_Queue(m_MaxLen - 1)<br /> End If<br /> End Property</p><p> '插入隊列元素<br /> Public Sub Insert(ByVal v)<br /> m_Queue(m_WriteIndex Mod m_MaxLen) = v<br /> m_WriteIndex = m_WriteIndex + 1<br /> If m_WriteIndex > m_MaxLen Then m_HeadOffset = (m_HeadOffset + 1) Mod m_MaxLen<br /> End Sub</p><p> '刪除隊列元素<br /> Public Sub Delete()<br /> Dim varEmpty<br /> m_Queue(m_HeadOffset) = varEmpty '將隊列的列首元素置為未初始化<br /> m_HeadOffset = (m_HeadOffset + 1) Mod m_MaxLen<br /> End Sub</p><p> '清空隊列<br /> Public Sub Clear()<br /> ReDim m_Queue(m_MaxLen)<br /> m_WriteIndex = 0<br /> m_HeadOffset = 0<br /> End Sub</p><p> '獲得隊列數組<br /> Public Property Get GetQueue()<br /> Dim i, n, trueLen</p><p> n = 0<br /> ReDim m_RetQueue(m_MaxLen - 1)<br /> For i = m_HeadOffset To m_MaxLen - 1<br /> If IsEmpty(m_Queue(i)) Then Exit For<br /> m_RetQueue(n) = m_Queue(i)<br /> n = n + 1<br /> Next<br /> trueLen = i - m_HeadOffset<br /> For i = 0 To m_HeadOffset - 1<br /> If IsEmpty(m_Queue(i)) Then Exit For<br /> m_RetQueue(n) = m_Queue(i)<br /> n = n + 1<br /> Next<br /> If trueLen > 0 Then<br /> trueLen = trueLen + i<br /> ReDim Preserve m_RetQueue(trueLen - 1)<br /> GetQueue = m_RetQueue<br /> End If<br /> End Property<br />'End Class '在ASP、WSH、HTML的VBScript指令碼中使用時需加此句</p><p>
然後,我們再來看一下在VB中如何使用此類:
Sub main()<br /> Dim objQueue<br /> Dim i, nLen</p><p> Set objQueue = New Queue<br /> '將隊列長度置為5<br /> nLen = 5<br /> objQueue.MaxLen = nLen</p><p> '向隊列插入元素(不超過隊列長度)<br /> For i = 1 To nLen<br /> objQueue.Insert i<br /> Next<br /> '顯示結果<br /> DisplayQueue objQueue</p><p> '清空隊列後重新插入元素(超過隊列長度)<br /> objQueue.Clear<br /> For i = 1 To nLen + 1<br /> objQueue.Insert i<br /> Next<br /> '顯示結果<br /> DisplayQueue objQueue</p><p> '刪除隊列元素<br /> objQueue.Delete<br /> '顯示結果<br /> DisplayQueue objQueue<br />End Sub</p><p>Private Sub DisplayQueue(qu)<br /> Dim v(), i<br /> v = qu.GetQueue<br /> For i = 0 To qu.MaxLen - 1<br /> If IsEmpty(v(i)) Then Exit For<br /> Debug.Print "第" & i + 1 & "個元素的值:", v(i)<br /> Next<br /> Debug.Print "------顯示完畢------"<br />End Sub<br />
看過了VB使用方法後,我們再來看一下在HTML的VBScript指令碼中如何使用,需要注意的是,要想測試結果,必須將以下代碼複製到記事本後另存新檔副檔名為html或htm的檔案,然後使用IE開啟,對於類代碼,讀者也可以單獨取出來存為vbs檔案,然後html裡包含它就可以了。至於ASP,思路與此完全一樣。
<html></p><p><head><br /><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><br /><title>建立網頁 1</title><br /></head></p><p><body><br /></body><br /></html><br /><mce:script language=vbscript><!--<br />Option Explicit<br />'* ************************************************************** *<br />'* 程式名稱:Queue.cls<br />'* 程式功能:一個VB迴圈隊列類<br />'* 作者:lyserver<br />'* 連絡方式:http://blog.csdn.net/lyserver<br />'* ************************************************************** *<br />Class Queue<br />Dim m_Queue() '隊列<br />Dim m_RetQueue() '隊列傳回值<br />Dim m_ReadIndex '列首位移索引<br />Dim m_WriteIndex '元素插入位移索引<br />Dim m_MaxLen '隊列最大尺寸</p><p>Private Sub Class_Initialize()<br /> m_ReadIndex = 0<br /> m_WriteIndex = 0<br /> m_MaxLen = 20 '隊列預設大小為20<br /> ReDim m_Queue(m_MaxLen - 1)<br />End Sub</p><p>Private Sub Class_Terminate()<br /> Erase m_Queue<br /> Erase m_RetQueue<br />End Sub</p><p>'獲得隊列大小<br />Public Property Get MaxLen()<br /> MaxLen = m_MaxLen<br />End Property</p><p>'設定隊列大小<br />Public Property Let MaxLen(ByVal NewValue)<br /> If NewValue > 0 Then<br /> m_MaxLen = NewValue<br /> ReDim m_Queue(m_MaxLen)<br /> End If<br />End Property</p><p>'插入隊列元素<br />Public Sub Insert(ByVal v)<br /> If m_WriteIndex = m_MaxLen Then '隊列已滿,擠掉最先插入的元素<br /> m_WriteIndex = 0<br /> m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen<br /> End If<br /> m_Queue(m_WriteIndex) = v<br /> m_WriteIndex = m_WriteIndex + 1<br />End Sub</p><p>'刪除隊列元素(按隊列原則,實際上是刪除最先插入的元素)<br />Public Sub Delete()<br /> Dim vTemp<br /> m_Queue(m_ReadIndex) = vTemp '將此變數置為未初始化<br /> m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen<br />End Sub</p><p>'清空隊列<br />Public Sub Clear()<br /> ReDim m_Queue(m_MaxLen)<br /> m_WriteIndex = 0<br /> m_ReadIndex = 0<br />End Sub</p><p>'獲得隊列數組<br />Public Property Get GetQueue()<br /> Dim i, n</p><p> n = 0<br /> ReDim m_RetQueue(m_MaxLen)<br /> For i = m_ReadIndex To m_MaxLen - 1<br /> If IsEmpty(m_Queue(i)) Then Exit For<br /> m_RetQueue(n) = m_Queue(i)<br /> n = n + 1<br /> Next<br /> For i = 0 To m_ReadIndex - 1<br /> If IsEmpty(m_Queue(i)) Then Exit For<br /> m_RetQueue(n) = m_Queue(i)<br /> n = n + 1<br /> Next<br /> GetQueue = m_RetQueue<br />End Property</p><p>End Class</p><p>Sub window_onload<br /> Dim objQueue<br /> Dim i, nLen</p><p> Set objQueue=New Queue</p><p> '將隊列長度置為5<br /> nLen = 5<br /> objQueue.MaxLen = nLen</p><p> '向隊列插入元素(不超過隊列長度)<br /> For i = 1 To nLen<br /> objQueue.Insert i<br /> Next<br /> '顯示結果<br /> DisplayQueue objQueue</p><p> '清空隊列後重新插入元素(超過隊列長度)<br /> objQueue.Clear<br /> For i = 1 To nLen + 1<br /> objQueue.Insert i<br /> Next<br /> '顯示結果<br /> DisplayQueue objQueue</p><p> '刪除隊列元素<br /> objQueue.Delete<br /> '顯示結果<br /> DisplayQueue objQueue<br />End Sub</p><p>Sub DisplayQueue(qu)<br /> Dim v,i<br /> v = qu.GetQueue<br /> For i = 0 To qu.MaxLen - 1<br /> If IsEmpty(v(i)) Then Exit For<br /> document.write "第" & i + 1 & "個元素的值:" & v(i) & "<br>"<br /> Next<br /> document.write "------顯示完畢------<br>"<br />End Sub<br />// --></mce:script>
怎麼樣?如果讀者覺得不滿意,歡迎您留下寶貴的意見!