C言語関係掲示板

過去ログ

No.936 処理系に依存せずにアルファベット順に並び替える

[戻る] [ホームページ]
No.11880

バブル・ソート法でアルファベット順に並び替える
投稿者---C言語初心者(2004/01/17 00:21:25)


この問題がわかりません。教えてください。お願いします。
バブル・ソート法による分類プログラムを作成し、10個以上の適当なデータを入力し、アルファベット順に並び替えよ。入力データは、40文字以内の文字列とする。

No.11882

Re:バブル・ソート法でアルファベット順に並び替える
投稿者---YuO(2004/01/17 12:58:55)


>バブル・ソート法による分類プログラムを作成し、10個以上の適当なデータを入力し、アルファベット順に並び替えよ。入力データは、40文字以内の文字列とする。

バブルソート自体はネットを探せば見つかるでしょうから省略しますが,
「アルファベット順」というのは非常に難解です。
#「英字」アルファベットならある程度なんとかなりますが……。

とりあえず,
#include <wchar.h>
#include <wctype.h>

/*! @fn int alphabeticCompare (const wchar_t * str1, const wchar_t * str2, const wchar_t * alphabets, wctrans_t desc)
 *
 *  アルファベット順(並びはユーザー指定)の文字列比較を行います。
 *  ISO/IEC 9899/AMD 1:1995以降のコンパイラが必須です。
 *
 *  @param str1 比較するワイド文字列。
 *  @param str2 比較されるワイド文字列。
 *  @param alphabets アルファベット順を規定するワイド文字列。
 *  @param desc 文字を変換するために使う,wctrans関数の戻り値。変換が不要なら0。
 *
 *  @retval 正の値 str1がstr2より前にある。
 *  @retval 0 str1がstr2と等しい。
 *  @retval 負の値 str1がstr2より後にある。
 *
 *  @warning alphabetsに存在しない文字は文字の終端を意味するものとして扱われます。
 */
int alphabeticCompare (const wchar_t * str1, const wchar_t * str2,
                       const wchar_t * alphabets, wctrans_t desc)
{
    const wchar_t * p1, * p2;

    for (;;) {
        if (desc) {
            p1 = wcschr(alphabets, towctrans(*str1, desc));
            p2 = wcschr(alphabets, towctrans(*str2, desc));
        } else {
            p1 = wcschr(alphabets, *str1);
            p2 = wcschr(alphabets, *str2);
        }

        if (!*str1) p1 = 0;
        if (!*str2) p2 = 0;

        if (p1 == 0 || p2 == 0 || p1 !=  p2) break;
        ++str1, ++str2;
    }

    if (p1 == 0 || p2 == 0) return (p1 == 0) - (p2 == 0);
    return p1 - p2;
}

である程度は処理できるかと。
ちゃんとロケールを設定してalphabetsを指定すれば,éなども扱えますし,
大文字にして比較/小文字にして比較などはdescで指定できます。

ただ,ドイツ語ロケールにおいてßをssとして比較,ということをやるなら,
もっと込み入ったプログラムが必要になります。


No.11887

Re:バブル・ソート法でアルファベット順に並び替える
投稿者---C言語初心者(2004/01/17 16:16:50)


解答ありがとうございます。難解なプログラムでびっくりです。これからもっともっと勉強しなければって感じですね。努力して理解してみます。

No.11890

Re:バブル・ソート法でアルファベット順に並び替える
投稿者---YuO(2004/01/17 17:15:08)


>解答ありがとうございます。難解なプログラムでびっくりです。

難解になったのは,条件があまりにも適当だったためです。

アルファベットと言っても,英字アルファベットを意味するのか,
ギリシャアルファベットを意味するのか,といった根本的な部分や,
ウムラウトなどの記号がつくのか否かといった部分も気にする必要があります。

順序付けでも,大文字にして調べるのがよい場合や小文字にして調べるのがよい場合,
#大文字と小文字は一対一で対応しているとは限らない
全く異なるアルゴリズムを必要とする場合もあります。

さらに,入力が1バイトの文字のみからなるのか,
それとも(日本語のような)多バイト文字からなるのかの指定もありませんでした。


これらの条件の下である程度はましな処理をしようとしたら,あのようになりました。


入力が1バイト文字のみで英字アルファベットのみ,記号は付かずUS-ASCIIの処理系,
全文字大文字(小文字)変換という条件下であれば,非常に簡単な関数が作れます。
#Aとaは等価と見なす場合