【C言語】構造体を線形探索する方法を解説

この記事では、構造体の配列を作成し、その中から特定の条件に合う要素を見つける方法をわかりやすく解説します。

基本的な実装から応用例まで、初心者でも理解できるようにサンプルコードとともに説明しますので、ぜひ参考にしてください。

目次から探す

構造体を用いた線形探索の実装

C言語で構造体を用いた線形探索を実装する方法について解説します。

線形探索は、配列やリストの中から特定の条件に合致する要素を見つけるための基本的なアルゴリズムです。

ここでは、構造体の配列を作成し、その中から特定の条件に合致する要素を線形探索する方法を説明します。

構造体の配列を作成する

まず、構造体の配列を作成します。

ここでは、例として「学生」の情報を持つ構造体を定義し、その配列を作成します。

構造体の配列の宣言

構造体の宣言は以下のように行います。

ここでは、学生の名前、年齢、IDを持つ構造体を定義します。

#include <stdio.h>
#include <string.h>
// 学生の情報を持つ構造体
typedef struct {
    char name[50];
    int age;
    int id;
} Student;

構造体の配列の初期化

次に、構造体の配列を宣言し、初期化します。

ここでは、3人の学生の情報を持つ配列を作成します。

int main() {
    // 構造体の配列を宣言し、初期化
    Student students[3] = {
        {"Alice", 20, 1},
        {"Bob", 21, 2},
        {"Charlie", 22, 3}
    };
    // 配列の内容を表示
    for (int i = 0; i < 3; i++) {
        printf("Name: %s, Age: %d, ID: %d\n", students[i].name, students[i].age, students[i].id);
    }
    return 0;
}

線形探索関数の作成

次に、構造体の配列を線形探索する関数を作成します。

この関数は、特定のIDを持つ学生を探すものとします。

関数のプロトタイプ宣言

関数のプロトタイプ宣言は以下のように行います。

// 線形探索関数のプロトタイプ宣言
int findStudentById(Student students[], int size, int id);

関数の実装

次に、関数の実装を行います。

この関数は、学生の配列とそのサイズ、探したいIDを引数に取り、該当する学生のインデックスを返します。

見つからない場合は-1を返します。

// 線形探索関数の実装
int findStudentById(Student students[], int size, int id) {
    for (int i = 0; i < size; i++) {
        if (students[i].id == id) {
            return i; // 該当する学生のインデックスを返す
        }
    }
    return -1; // 見つからない場合は-1を返す
}

線形探索関数の呼び出し

最後に、線形探索関数を呼び出して、特定のIDを持つ学生を探します。

関数の引数と戻り値

関数の引数には、学生の配列、配列のサイズ、探したいIDを渡します。

戻り値は、該当する学生のインデックスです。

関数の呼び出し例

以下に、線形探索関数を呼び出す例を示します。

int main() {
    // 構造体の配列を宣言し、初期化
    Student students[3] = {
        {"Alice", 20, 1},
        {"Bob", 21, 2},
        {"Charlie", 22, 3}
    };
    // 探したいID
    int targetId = 2;
    // 線形探索関数を呼び出し
    int index = findStudentById(students, 3, targetId);
    // 結果を表示
    if (index != -1) {
        printf("Found student: Name: %s, Age: %d, ID: %d\n", students[index].name, students[index].age, students[index].id);
    } else {
        printf("Student with ID %d not found.\n", targetId);
    }
    return 0;
}

このプログラムを実行すると、IDが2の学生(Bob)の情報が表示されます。

見つからない場合は Student with ID 2 not found. と表示されます。

以上が、C言語で構造体を用いた線形探索の実装方法です。

構造体の配列を作成し、線形探索関数を実装して呼び出すことで、特定の条件に合致する要素を効率的に見つけることができます。

応用例

ここでは、構造体を用いた線形探索の応用例について解説します。

基本的な線形探索の方法を理解した上で、さらに複雑な条件や動的な変更に対応する方法を学びましょう。

複数の条件での線形探索

複数の条件で線形探索を行う場合、条件を組み合わせて探索を行います。

例えば、以下のような構造体 Person があるとします。

#include <stdio.h>
#include <string.h>
typedef struct {
    char name[50];
    int age;
    char city[50];
} Person;

この構造体の配列から、特定の年齢と都市に一致する人物を探す場合のコードは以下のようになります。

int findPersonByAgeAndCity(Person people[], int size, int age, const char* city) {
    for (int i = 0; i < size; i++) {
        if (people[i].age == age && strcmp(people[i].city, city) == 0) {
            return i; // 見つかった場合のインデックスを返す
        }
    }
    return -1; // 見つからなかった場合
}
int main() {
    Person people[3] = {
        {"Alice", 30, "Tokyo"},
        {"Bob", 25, "Osaka"},
        {"Charlie", 30, "Tokyo"}
    };
    int index = findPersonByAgeAndCity(people, 3, 30, "Tokyo");
    if (index != -1) {
        printf("Found: %s\n", people[index].name);
    } else {
        printf("Not Found\n");
    }
    return 0;
}

このコードでは、年齢が30歳で都市が東京の人物を探しています。

見つかった場合、その人物の名前を表示します。

構造体のメンバーを動的に変更する場合の線形探索

構造体のメンバーを動的に変更する場合、線形探索の結果に基づいて特定のメンバーを更新することができます。

例えば、特定の人物の年齢を更新する場合のコードは以下のようになります。

void updatePersonAge(Person people[], int size, const char* name, int newAge) {
    for (int i = 0; i < size; i++) {
        if (strcmp(people[i].name, name) == 0) {
            people[i].age = newAge;
            return;
        }
    }
}
int main() {
    Person people[3] = {
        {"Alice", 30, "Tokyo"},
        {"Bob", 25, "Osaka"},
        {"Charlie", 30, "Tokyo"}
    };
    updatePersonAge(people, 3, "Alice", 35);
    for (int i = 0; i < 3; i++) {
        printf("Name: %s, Age: %d, City: %s\n", people[i].name, people[i].age, people[i].city);
    }
    return 0;
}

このコードでは、名前が Alice の人物の年齢を35歳に更新しています。

更新後の結果を表示することで、変更が正しく行われたことを確認できます。

構造体のネストと線形探索

構造体のネストとは、ある構造体のメンバーとして別の構造体を持つことです。

例えば、以下のような構造体 AddressPerson があるとします。

typedef struct {
    char street[50];
    char city[50];
    char state[50];
} Address;
typedef struct {
    char name[50];
    int age;
    Address address;
} Person;

この構造体の配列から、特定の都市に住む人物を探す場合のコードは以下のようになります。

int findPersonByCity(Person people[], int size, const char* city) {
    for (int i = 0; i < size; i++) {
        if (strcmp(people[i].address.city, city) == 0) {
            return i; // 見つかった場合のインデックスを返す
        }
    }
    return -1; // 見つからなかった場合
}
int main() {
    Person people[3] = {
        {"Alice", 30, {"123 Main St", "Tokyo", "Tokyo"}},
        {"Bob", 25, {"456 Elm St", "Osaka", "Osaka"}},
        {"Charlie", 30, {"789 Oak St", "Tokyo", "Tokyo"}}
    };
    int index = findPersonByCity(people, 3, "Tokyo");
    if (index != -1) {
        printf("Found: %s\n", people[index].name);
    } else {
        printf("Not Found\n");
    }
    return 0;
}

このコードでは、住所の都市が Tokyo の人物を探しています。

見つかった場合、その人物の名前を表示します。

以上のように、構造体を用いた線形探索は、複数の条件や動的な変更、ネストされた構造体にも対応することができます。

これらの応用例を参考にして、より複雑なデータ構造を扱うプログラムを作成してみてください。

目次から探す