enchanのメモ書き

計算機とフリルとラブライブ!

構造体のソートを考える

お久しぶりです。 あまりに忙しすぎて ここ二ヶ月の記憶がほとんどありません。
去年1年だらけきった身には今年のテストはあまりに重すぎた…!

今日はCのお話です。やりたいことはとっても単純。

Cのリハビリ中

思い出したかのように 約3年前に作ったC製のちっちゃなCLI を引っ張り出してきて 大改造!!劇的ビフォーアフター しています。
とりあえず cmakeを何一つ理解していない ことが理解できました。 ダメじゃねえか。

図1. ダニング=クルーガー効果の曲線上で確率的勾配降下法に基づく学習を行う人

…まあ、CLIツールとなれば実行引数のパースのひとつやふたつやってみたくなるわけです。 ついでになんかGNUっぽく --help とか --version とかやってみたい (幼児)。
となると必然的に getopt.hgetopt_long あたりを使うことになるわけですが、この関数に渡す struct option をぼんやり見つめていてふと思ったのです。

qsortで構造体ソートしたらどうなるんだろ〜〜〜〜

実際にやってみた

こんなミクロなネタでも記事にします。
そしてC言語の場合たいていこういうところでとんでもないポインタの使い方とかallocするメモリの量が少なすぎるとかバッファオーバーランの危険性を孕む関数とかメモリリークしてるとかぞろぞろ出てきて集中砲火がうわなにするやめ

/**
 * @struct item
 * @brief アイテム
 */
struct item {
    int id;              // 識別子
    char* name;          // アイテム名
    unsigned int count;  // 個数
};

こんな構造体を用意しました。 RPGによくあるアイテムをイメージしたものです。

なんかこんな感じの比較関数を作って:

/**
 * @fn compare_by_count
 * @brief 個数で昇順に並べ替え
 */
int compare_by_count(const void* a, const void* b) {
    return ((const struct item*)a)->count - ((const struct item*)b)->count;
}

/**
 * @fn compare_by_id
 * @brief IDで昇順に並べ替え
 */
int compare_by_id(const void* a, const void* b) {
    return ((const struct item*)a)->id - ((const struct item*)b)->id;
}

qsortに渡してソートさせると…

% gcc main.c && ./a.out

Before sort
#2: super potion (2x)
#10: wooden sword (1x)
#1: high potion (4x)
#11: wooden shield (2x)
#31: spell-book #2 (1x)
#30: spell-book #1 (2x)
#0: potion (10x)
#21: old letter (1x)
#20: secret key (1x)

Sort by count
#21: old letter (1x)
#20: secret key (1x)
#31: spell-book #2 (1x)
#10: wooden sword (1x)
#11: wooden shield (2x)
#2: super potion (2x)
#30: spell-book #1 (2x)
#1: high potion (4x)
#0: potion (10x)

Sort by id
#0: potion (10x)
#1: high potion (4x)
#2: super potion (2x)
#10: wooden sword (1x)
#11: wooden shield (2x)
#20: secret key (1x)
#21: old letter (1x)
#30: spell-book #1 (2x)
#31: spell-book #2 (1x)

おぉー… (本人にしか分からないほどささやかな満足感)
深夜はこういうなんの生産性もないちっちゃなTipsが沁みますね。 (current: 23:02)

共用体のソートとか考えると…ビット列単位でソートできるあたり、ちょっと面白そう? 用途はともかく

なんかゲーム作りたくなっちゃった

ソートのサンプルにアイテムなんて概念を使ったせいで何年も前に冬眠状態に入ったはずの ゲーム作りを司る神経が刺激されてしまいました。 (中学の頃授業中ずーーーーっとノートの片隅にRPGのプロットを書いていたタイプの変人)
この「0番台は即時使用アイテム、10番台は装備、20番台は重要なアイテム、30番台は個数減る系のスキル習得アイテム」…な構造は昔からずっとこのままです。なんなんでしょうね、こういうの。
結局プロットだけ練って満足するというのがいつものパターンでした。これもなんなんでしょうね()

オチはない

今日はただ構造体をqsortするってことがやりたかっただけなので、オチはないです。こいつ毎回オチ見失ってんな。
あ、そういえば C100お疲れ様でした(10倍に薄めたC1000ではない)。 通販ではあるものの「 進捗: 新刊を購入する 」 は達成できたので満足です。

おやすみなさい。

fflush(stdout)