文字列の頭2桁の数字を年に変換してソートしたい

文字列の頭2桁の数字を年に変換してソートしたいという問題を拝借しました。 西暦は 4 桁で書く人が多いような気がしますが、2 桁で書く人も見かけます。

問題は情報の欠落しているものをどうやって補うか、というところですが、何となく 1970 年という年を使ってしまいました。 1970 年というのはコンピュータの世界ではエポックタイムとして知られ、この前も1234567890 秒までの残り時間を表示するというお題を解いたばかりですから、覚えている方もいると思います。 また、ソートはgawk のビルトイン asort() はオレ quick sort より速いで用いたクイックソート (Quick Sort) を用いています。

個人的な癖もあるのですが、既存の sort に手を入れるのではなく、あらかじめデータを sort できる形に準備しておく方が様々な sort に対応できるので好んで使います。

#! /usr/bin/gawk -f
# key_sort_2.awk

{
    a[NR] = substr($0, 1, 2) + 0 >= 70 ? "19" $0 : "20" $0;
}

END {
    # Quick Sort
    quick_sort(a, 1, NR);

    # ソートされた配列の表示
    for (i = 1; i <= NR; i++) {
        print substr(a[i], 3);
    }
}

# quick_sort():     再帰版 Quick Sort
#   in:     配列 arr
#           最初のインデックス left
#           最後のインデックス right
#   out:    ソートされた配列
function quick_sort(array, left, right,     i, j, tmp, pivot) {
    if (left < right) {
        i = left;
        j = right;
        pivot = array[int((left + right) / 2)];
        while (i <= j) {
            while (array[i] < pivot) {
                i++;
            }
            while (array[j] > pivot) {
                j--;
            }
            if (i <= j) {
                tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
                i++;
                j--;
            }
        }
        quick_sort(array, left, j);
        quick_sort(array, i, right);
    }
}

これを実際に動かしてみます。 データは上記のページと同じものです。

$ cat key_sort_2.txt
07AA
06BB
05CC
00DD
98EE
97FF
$ gawk -f key_sort_2.awk key_sort_2.txt
97FF
98EE
00DD
05CC
06BB
07AA

無事、並べることができました。

tag_nawk.pngtag_nawk.pngtag_nawk.pngtag_nawk.png