[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; // 交換がなければ終了
}このように、バブルソートの基本的な実装に工夫を加えることで、特定の要件に応じたソートを実現できます。
まとめ
バブルソートは、シンプルで理解しやすいソートアルゴリズムであり、小規模なデータセットや教育目的に適しています。
この記事では、文字列の配列をバブルソートする方法を解説し、応用例や注意点についても触れました。
これを機に、他のソートアルゴリズムにも挑戦し、より効率的なプログラムを作成してみてください。
 
![[C言語] ドラゴン曲線を計算するプログラムを実装する方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44015.png)
![[C言語] トポロジカルソートを実装する方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44014.png)
![[C言語] ハノイの塔を解くプログラムの作成方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44019.png)
![[C言語] はさみうち法(非線形方程式)を実装する方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44017.png)
![[C言語] ナップザック問題を動的計画法で解く方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44016.png)
![[C言語] フラクタル圧縮を用いた画像圧縮方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44023.png)
![[C言語] プサイ関数/ポリガンマ関数を実装する方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44022.png)
![[C言語] フィボナッチ探索を実装する方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44021.png)
![[C言語] フィボナッチ数列を求めるアルゴリズムの書き方](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44020.png)
![[C言語] ベルマンフォード法を実装する方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44029.png)
![[C言語] ベータ分布を計算して乱数を生成する方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44028.png)
![[C言語] ベータ関数を実装する方法](https://af-e.net/wp-content/uploads/2024/09/thumbnail-44027.png)