aodama.gif(0.97KB) 文字列のソート

 数値のクイックソート処理が完成したので、 ついでに文字列のソート処理も作ってみました。

    strArray(0) = "Error"
    strArray(1) = "Aho no Sakata"
    strArray(2) = "Cool"
のように順序がバラバラな文字列型配列を、
    strArray(0) = "Aho no Sakata"
    strArray(1) = "Cool"
    strArray(2) = "Error"
のように正順に整列します。文字列比較には VB の StrComp 関数を使用しています。

Option Explicit

'----- StrSort Ver 1.00 -----
'文字列型(String)配列をソートします。
'
'引数 strArray()
'   ソート対象となる文字列型(String)配列を指定します。
'       strArray(0) = "Error"
'       strArray(1) = "Aho no Sakata"
'       strArray(2) = "Cool"
'   の配列を渡した場合、
'       strArray(0) = "Aho no Sakata"
'       strArray(1) = "Cool"
'       strArray(2) = "Error"
'   のように正順に整列されます。
'
'引数 lngStart
'   ソートを開始する配列の要素番号を指定します。
'
'引数 lngEnd
'   ソートを終了する配列の要素番号を指定します。
'
'引数 lngCompare
'   省略可能です。文字列比較のモードを指定する番号を設定します。
'
'   vbBinaryCompare - バイナリ モードの比較を行います。
'   vbTextCompare   - テキスト モードの比較を行います。
'
'   この引数を省略すると vbBinaryCompare が適用されます。
'
'ソートにはクイックソートアルゴリズムを使用し、文字列比較には
'StrComp 関数を使用しています。ソートアルゴリズム自体は
'高速なのですが、可変長文字列型配列を扱うため処理速度は決して
'速いとはいえません。また時間があったら最適化処理でも考えます。
'
Public Sub StrSort _
    (ByRef strArray() As String, _
     ByVal lngStart As Long, _
     ByVal lngEnd As Long, _
     Optional ByVal lngCompare As Long)

 Dim lngBaseNumber As Long                                          '中央の要素番号を格納する変数
 Dim strBaseValue As String                                         '基準値を格納する変数
 Dim lngCounter As Long                                             '格納位置カウンタ
 Dim strBuffer As String                                            '値をスワップするための作業域
 Dim i As Long                                                      'ループカウンタ
 
    If lngStart >= lngEnd Then Exit Sub                             '終了番号が開始番号以下の場合、プロシージャを抜ける
    lngBaseNumber = (lngStart + lngEnd) \ 2                         '中央の要素番号を求める
    strBaseValue = strArray(lngBaseNumber)                          '中央の値を基準値とする
    strArray(lngBaseNumber) = strArray(lngStart)                    '中央の要素に開始番号の値を格納
    lngCounter = lngStart                                           '格納位置カウンタを開始番号と同じにする
    For i = (lngStart + 1) To lngEnd Step 1                         '開始番号の次の要素から終了番号までループ
        If StrComp(strArray(i), strBaseValue, lngCompare) = -1 Then '値が基準値より小さい場合
            lngCounter = lngCounter + 1                             '格納位置カウンタをインクリメント
            strBuffer = strArray(lngCounter)                        'strArray(i) と strArray(lngCounter) の値をスワップ
            strArray(lngCounter) = strArray(i)
            strArray(i) = strBuffer
        End If
    Next i
    strArray(lngStart) = strArray(lngCounter)                       'strArray(lngCounter) を開始番号の値にする
    strArray(lngCounter) = strBaseValue                             '基準値を strArray(lngCounter) に格納
    Call StrSort(strArray(), lngStart, lngCounter - 1)              '分割された配列をクイックソート(再帰)
    Call StrSort(strArray(), lngCounter + 1, lngEnd)                '分割された配列をクイックソート(再帰)

End Sub

サンプル : ダウンロード strsort.lzh(3.30KB)

 クラスモジュールを使用すれば、比較用クラスを作成して、 色々なデータ型に対応できるクイックソート関数も作れると思います。 C 言語の qsort のように汎用性の高いクイックソートが作れることでしょう。 しかし私はクラスモジュールの使い方をよく知らないので作れません(^-^;


VBコーナーにもどる   トップページにもどる