바라기의 이야기

퀵소트(Quick Sort)를 이용한 Notes Document 소트 본문

Develop/Domino

퀵소트(Quick Sort)를 이용한 Notes Document 소트

baragi76 2010. 3. 14. 23:55

Web 개발시 문서를 소트해야할 경우가 발생합니다.
일반적으로 NotesView를 사용하면 손쉽게 소트를 수행할 수 있으나, 도미노는 검색후 결과값에 대해 매우 한정적인 정렬방식을 제공하고, 이를 이용하여 개발을 할 경우 원하는 결과를 보여주지 못하는 경우가 많습니다.

아래의 코드는 검색후 결과 NotesDocumentCollection의 Document들의 UNID와 소트하고자하는 Field값을 각각 배열에 넣고, 해당 배열을 QuickSort 함수의 인자로해서 넘기면 원하는 순서대로 UNID 배열을 반환합니다.

일반적으로 정렬같은 경우 손쉽게 처리하기 위해 버블소트를 사용하지만 정렬을 하고자하는 대상이 많아지면 처리수행 시간은 엄청 길어 질 수 밖에 없습니다.
물론 퀵소트라고 할지라도 수많은 문서의 정렬이 필요한 경우 늦어질 수 밖에 없는데 이는 정렬을 수행하는 코드에서의 지연이라기 보다 해당되는 수 많은 문서의 UNID와 SortKey를 배열에 담는 과정에서 발생하는 시간일 것입니다.


---------------------------------------------------------------------------------------------------
트리거:        수행 메뉴에서 수동으로
실행:        선택된 문서

LotusScript 코드:
Option Public
Dim ss As NotesSession
Dim curDb As NotesDatabase
Dim Docs As NotesDocumentCollection
Dim Doc As NotesDocument
Const SORT_ASCENDING = "asc"
Const SORT_DESCENDING = "des"
Sub Initialize
        Set ss = New NotesSession
        Set curDb = ss.CurrentDatabase
        Set Docs = curDb.UnprocessedDocuments
        Set Doc = Docs.GetFirstDocument
        Dim sortItem() As String
        Dim unid() As String
        Dim index As Integer
        Dim resultUNID As Variant
        index = 0
        While( Not Doc Is Nothing )
                Redim Preserve sortItem(index) As String
                Redim Preserve unid(index) As String
                sortItem(index) = Doc.Subject(0)
                unid(index) = Doc.UniversalID
                index = index + 1
                Set Doc = Docs.GetNextDocument( Doc )
        Wend
        resultUNID = QuickSort( sortItem, unid, SORT_DESCENDING, 0, Ubound(sortItem) )
        Forall rID In resultUNID
                Print Cstr( rID )
        End Forall
End Sub
Function QuickSort( source As Variant, unid As Variant, opt As String, lo0 As Integer, hi0 As Integer )As Variant
%REM
        source 값을 키값으로하여 unid 정렬 (퀵소트)
        인수 :
                source         : sortkey( 정렬키 )
                unid                : 문서 ID 목록
                opt                        : 정렬( 오름차순:asc, 내림차순:des )
                lo0                        : 퀵소트를 위한 low값
                hi0                        : 퀵소트를 위한 high값
%END REM
        On Error Goto ErrorHandle
        Dim lo As Integer
        Dim hi As Integer
        Dim midValue As String
        lo = lo0
        hi = hi0
        If( hi0 > lo0 ) Then
                midValue = source((lo0 + hi0 ) / 2)
                While( lo <= hi )
                        If( opt = SORT_ASCENDING ) Then
                                While( ( lo < hi0 ) And ( source(lo) < midValue ))
                                        lo = lo + 1
                                Wend
                                While( ( lo0 < hi ) And ( source(hi) > midValue ))
                                        hi = hi - 1
                                Wend
                                If( lo <= hi ) Then
                                        Call swap( source, lo, hi )
                                        Call swap( unid, lo, hi )
                                        lo = lo + 1
                                        hi = hi -1
                                End If
                        Else
                                While( ( lo < hi0 ) And ( source(lo) > midValue ))
                                        lo = lo + 1
                                Wend
                                While( ( lo0 < hi ) And ( source(hi) < midValue ))
                                        hi = hi - 1
                                Wend
                                If( lo <= hi ) Then
                                        Call swap( source, lo, hi )
                                        Call swap( unid, lo, hi )
                                        lo = lo + 1
                                        hi = hi -1
                                End If
                        End If
                Wend
                If( lo0 < hi ) Then
                        Call QuickSort( source, unid, opt, lo0, hi )
                End If
                If( lo < hi0 ) Then
                        Call QuickSort( source, unid, opt, lo, hi0 )
                End If
        End If
        QuickSort = unid
        Exit Function
ErrorHandle:
        Msgbox "문서소트::QuickSort[" + Cstr(Erl() ) + "] : " + Error
        Print "문서소트::QuickSort[" + Cstr(Erl() ) + "] : " + Error
        Exit Function
End Function
Sub Swap( source As Variant, i As Integer, j As Integer )
%REM
        source값의 i번째 값과 j번째 값 교체
        인수 :
                source         : 배열
                i, j                        : 교체하려는 배열의 index 값
%END REM
        Dim tmp As String
        tmp = source(i)
        source(i) = source(j)
        source(j) = tmp
End Sub