[C言語] 文字列の配列をバブルソートする方法を解説

C言語で文字列の配列をバブルソートするには、文字列の比較と交換を行う必要があります。

文字列の比較には標準ライブラリの関数strcmpを使用します。

この関数は、2つの文字列を比較し、同じ場合は0、最初の文字列が辞書順で小さい場合は負の値、大きい場合は正の値を返します。

バブルソートでは、隣接する文字列をstrcmpで比較し、必要に応じて交換します。

この操作を配列の最後まで繰り返し、ソートが完了するまで続けます。

この記事でわかること
  • 文字列の配列をバブルソートする手順
  • 文字列の比較方法と注意点
  • バブルソートの応用例とその実装方法
  • バブルソートの利点と適用場面
  • ソートの効率化のための工夫

目次から探す

文字列の配列をバブルソートする手順

ソートのための準備

バブルソートを実装する前に、まずはソート対象となる文字列の配列を準備します。

C言語では、文字列は文字の配列として扱われるため、文字列の配列は二次元配列として定義します。

以下に例を示します。

#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 5
#define MAX_LENGTH 100
int main() {
    // 文字列の配列を定義
    char strings[MAX_STRINGS][MAX_LENGTH] = {
        "りんご",
        "バナナ",
        "オレンジ",
        "ぶどう",
        "メロン"
    };
    // ここにソート処理を追加
    return 0;
}

この例では、5つの文字列を持つ配列を定義しています。

それぞれの文字列は最大100文字まで格納可能です。

文字列の比較方法

文字列の比較には、strcmp関数を使用します。

この関数は、2つの文字列を辞書順で比較し、以下のような結果を返します。

スクロールできます
戻り値意味
< 0第一引数の文字列が第二引数の文字列より小さい
0両方の文字列が等しい
> 0第一引数の文字列が第二引数の文字列より大きい

この関数を利用して、文字列の順序を決定します。

バブルソートの実装手順

バブルソートは、隣接する要素を比較し、必要に応じて交換することでソートを行います。

以下に、文字列の配列をバブルソートするコードを示します。

#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 5
#define MAX_LENGTH 100
int main() {
    char strings[MAX_STRINGS][MAX_LENGTH] = {
        "りんご",
        "バナナ",
        "オレンジ",
        "ぶどう",
        "メロン"
    };
    // バブルソートの実装
    for (int i = 0; i < MAX_STRINGS - 1; i++) {
        for (int j = 0; j < MAX_STRINGS - i - 1; j++) {
            if (strcmp(strings[j], strings[j + 1]) > 0) {
                // 文字列の交換
                char temp[MAX_LENGTH];
                strcpy(temp, strings[j]);
                strcpy(strings[j], strings[j + 1]);
                strcpy(strings[j + 1], temp);
            }
        }
    }
    // ソート結果の表示
    printf("ソート後の文字列:\n");
    for (int i = 0; i < MAX_STRINGS; i++) {
        printf("%s\n", strings[i]);
    }
    return 0;
}

このコードでは、strcmp関数を用いて隣接する文字列を比較し、必要に応じてstrcpy関数で文字列を交換しています。

ソートの終了条件

バブルソートは、配列全体を走査し、交換が行われなくなるまで繰り返します。

上記のコードでは、forループを用いて、配列の要素数に基づいてソートを行っています。

具体的には、iが0からMAX_STRINGS - 1まで、jが0からMAX_STRINGS - i - 1までの範囲でループを回し、隣接する要素を比較します。

このようにして、バブルソートは配列の全ての要素が正しい順序になるまで繰り返されます。

完成したプログラム

以下に、文字列の配列をバブルソートする完成したプログラムを示します。

このプログラムは、5つの日本語の果物名を含む文字列の配列を辞書順にソートします。

#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 5
#define MAX_LENGTH 100
int main() {
    // 文字列の配列を定義
    char strings[MAX_STRINGS][MAX_LENGTH] = {
        "りんご",
        "バナナ",
        "オレンジ",
        "ぶどう",
        "メロン"
    };
    // バブルソートの実装
    for (int i = 0; i < MAX_STRINGS - 1; i++) {
        for (int j = 0; j < MAX_STRINGS - i - 1; j++) {
            if (strcmp(strings[j], strings[j + 1]) > 0) {
                // 文字列の交換
                char temp[MAX_LENGTH];
                strcpy(temp, strings[j]);
                strcpy(strings[j], strings[j + 1]);
                strcpy(strings[j + 1], temp);
            }
        }
    }
    // ソート結果の表示
    printf("ソート後の文字列:\n");
    for (int i = 0; i < MAX_STRINGS; i++) {
        printf("%s\n", strings[i]);
    }
    return 0;
}

プログラムの実行例

ソート後の文字列:
オレンジ
バナナ
ぶどう
メロン
りんご

このプログラムは、strcmp関数を使用して文字列を比較し、strcpy関数を用いて文字列を交換することで、配列を辞書順にソートします。

実行結果として、果物名がアルファベット順に並び替えられたことが確認できます。

応用例

大文字小文字を区別しないソート

C言語で大文字小文字を区別しないソートを行うには、strcasecmp関数を使用します。

この関数は、strcmpと同様に文字列を比較しますが、大文字小文字を区別しません。

以下に例を示します。

#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 5
#define MAX_LENGTH 100
int main() {
    char strings[MAX_STRINGS][MAX_LENGTH] = {
        "りんご",
        "バナナ",
        "オレンジ",
        "ぶどう",
        "メロン"
    };
    for (int i = 0; i < MAX_STRINGS - 1; i++) {
        for (int j = 0; j < MAX_STRINGS - i - 1; j++) {
            if (strcasecmp(strings[j], strings[j + 1]) > 0) {
                char temp[MAX_LENGTH];
                strcpy(temp, strings[j]);
                strcpy(strings[j], strings[j + 1]);
                strcpy(strings[j + 1], temp);
            }
        }
    }
    printf("大文字小文字を区別しないソート後の文字列:\n");
    for (int i = 0; i < MAX_STRINGS; i++) {
        printf("%s\n", strings[i]);
    }
    return 0;
}

ソート順を逆にする方法

ソート順を逆にするには、比較の条件を変更します。

strcmp関数の戻り値を逆に評価することで、降順にソートできます。

if (strcmp(strings[j], strings[j + 1]) < 0) {
    // 文字列の交換
    char temp[MAX_LENGTH];
    strcpy(temp, strings[j]);
    strcpy(strings[j], strings[j + 1]);
    strcpy(strings[j + 1], temp);
}

特定の文字列を優先するソート

特定の文字列を優先してソートするには、カスタムの比較関数を作成します。

例えば、「りんご」を最優先にする場合、以下のように実装します。

int customCompare(const char *a, const char *b) {
    if (strcmp(a, "りんご") == 0) return -1;
    if (strcmp(b, "りんご") == 0) return 1;
    return strcmp(a, b);
}

この関数をバブルソート内で使用します。

部分的なソートの実装

配列の一部だけをソートする場合、ソート範囲を指定してバブルソートを実行します。

例えば、配列の最初の3つの要素だけをソートする場合、ループの範囲を調整します。

for (int i = 0; i < 3 - 1; i++) {
    for (int j = 0; j < 3 - i - 1; j++) {
        if (strcmp(strings[j], strings[j + 1]) > 0) {
            char temp[MAX_LENGTH];
            strcpy(temp, strings[j]);
            strcpy(strings[j], strings[j + 1]);
            strcpy(strings[j + 1], temp);
        }
    }
}

ソートの効率化のための工夫

バブルソートは効率が悪いことで知られていますが、いくつかの工夫で改善できます。

例えば、交換が行われなかった場合にソートを終了することで、無駄なループを避けることができます。

int swapped;
for (int i = 0; i < MAX_STRINGS - 1; i++) {
    swapped = 0;
    for (int j = 0; j < MAX_STRINGS - i - 1; j++) {
        if (strcmp(strings[j], strings[j + 1]) > 0) {
            char temp[MAX_LENGTH];
            strcpy(temp, strings[j]);
            strcpy(strings[j], strings[j + 1]);
            strcpy(strings[j + 1], temp);
            swapped = 1;
        }
    }
    if (!swapped) break; // 交換がなければ終了
}

このように、バブルソートの基本的な実装に工夫を加えることで、特定の要件に応じたソートを実現できます。

よくある質問

バブルソートはどのような場合に適していますか?

バブルソートは、アルゴリズムが非常にシンプルで実装が容易なため、小規模なデータセットや教育目的での使用に適しています。

また、データがほぼ整列されている場合には、他のソートアルゴリズムと比較して効率的に動作することがあります。

ただし、大規模なデータセットには不向きで、効率の良いソートが求められる場合には他のアルゴリズムを検討することが推奨されます。

文字列の比較で注意すべき点は何ですか?

文字列の比較では、strcmp関数を使用する際に、文字列の終端を示すヌル文字\0まで正確に比較されることを理解しておく必要があります。

また、文字列の大文字小文字を区別するかどうかを考慮し、必要に応じてstrcasecmp関数を使用することも重要です。

さらに、比較の際に文字列が正しく初期化されていることを確認し、未定義の動作を避けるように注意しましょう。

他のソートアルゴリズムと比べてバブルソートの利点は何ですか?

バブルソートの主な利点は、そのシンプルさと実装の容易さです。

特に、プログラミング初心者にとっては、ソートアルゴリズムの基本的な概念を理解するための良い出発点となります。

また、バブルソートはインプレースで動作するため、追加のメモリを必要としないという利点もあります。

ただし、効率の面では他のソートアルゴリズムに劣るため、実用的な用途では注意が必要です。

まとめ

バブルソートは、シンプルで理解しやすいソートアルゴリズムであり、小規模なデータセットや教育目的に適しています。

この記事では、文字列の配列をバブルソートする方法を解説し、応用例や注意点についても触れました。

これを機に、他のソートアルゴリズムにも挑戦し、より効率的なプログラムを作成してみてください。

  • URLをコピーしました!
目次から探す