配列内に指定の値が存在するかを探索する_1(線形探索)

キーボードから入力された整数値が、
用意された配列内に存在するかを探索してみます。
探索方法は、
入力値と配列内数値の先頭から末尾まで
順番に比較していき、同値が存在した場合、その位置をキープします。
※配列内に入力値との同値が複数個存在する場合は、
 どのように処理(表示)するかによりアルゴリズムが変わりますね。
 1.最初に見つかった位置を探索位置とする
 2.最後に見つかった位置を探索位置とする
 3.見つかった全ての位置を探索値とする
 などです。

では、まず1.2.の条件での探索をプログラムしてみます。

・プロジェクトを作成します。
 Visual Studio 2022を起動し、
 新しいプロジェクトを作成します。
 ・プロジェクトタイプ:"コンソールアプリ"
 ・プロジェクト名:"ct_105_1"
 とします。

プロジェクトの作成
プロジェクトの作成

 ※プロジェクトの作成方法は、PCでC言語基礎編の
  ・2つの入力値(整数値)の四則演算結果を表示する
  を参考にして下さい。

・プログラム記述・編集画面が表示されるので、
 以下のプログラムを記述します。

プログラム記述前の編集画面
プログラム記述前の編集画面
プログラム記述後の編集画面1
プログラム記述後の編集画面1

 プログラムの記述内容

// 配列内より指定の値の有無を探索する_1

#include <iostream>

int main()
{
    // 変数宣言と初期化
    int array[] = { 1,2,3,4,5,6,7,3,9,10 };
    int target;
    int num;
    int position = -1;

    // キーボードからの探索数値を受け取る
    printf("探索数値:");
    scanf_s("%d", &target);

    // array配列の要素数を取得
    num = sizeof(array) / sizeof(array[0]);

    // 配列内を探索ループ
    for (int i = 0; i < num; i++) {
        if (target == array[i]) {
            position = i + 1;
            break;
        }
    }

    // 探索結果の表示
    if (position == -1) {
        printf("探索対象数値はありませんでした\n");
    }
    else {
        printf("対象数値は%d番目にありました\n", position);
    }

    return EXIT_SUCCESS;
}

 簡単なプログラム解説です。

  ・変数宣言と初期化
   int array[] = { 1,2,3,4,5,6,7,3,9,10 };
    探索対象とする配列を宣言します。
    ※数値 3 を2カ所に設定してあります。
   int target;
    キーボートから入力された探索対象数値を格納
   int num;
    ループ回数に利用する配列の要素数を格納するための変数
   int position = -1;
    探索結果とした配列内に対象が存在した場合、その添え字を格納する変数
    添え字は 0 から始まるので、探索失敗を確認できるよう
    -1 を初期設定しています。

  ・キーボードからの探索数値を受け取る
   printf("探索数値:");
   scanf_s("%d", &target);
    キーボードからの入力待ちであることがわかるよう、
    画面に、"探索数値:"と入力促進表示をし、
    キーボードからの入力値を変数 target に格納します。

  ・array配列の要素数を取得
   num = sizeof(array) / sizeof(array[0]);
    この式によって、配列内の要素数を取得し、
    変数 num に格納します。

  ・配列内の探索ループ
   for (int i = 0; i < num; i++) {
    if (target == array[i]) {
      position = i + 1;
      break;
    }
   }
    変数 i を要素番号指定変数 array[i] として、
    配列の先頭 array[0] から 末尾の array[9] まで
    キーボードから入力された値と格納している
    変数 target と比較しながら進めます。
    この時、変数 target と配列 array[i] とが一致した場合、
    変数 position に添え字 + 1 の値を位置として格納します。
    
    1.最初に見つかった位置を探索位置とする場合には、
    この時点で break文を発行してループ処理をから脱出します。
    ※繰り返し文内で、break文が発行(’実行)されると、
     その繰り替えし(ループ)はその時点で終了し、
     ループを抜けた次の文へと処理が移ります。    
    2.最後に見つかった位置を探索位置とする場合には、
    この break文 を発行せず、繰り返し処理を継続させます。
    これにより、変数 position には、
    最後に見つかった位置を格納することができます。
    ※以下のような、break文の無いループ(for( ))文に書き換えます。  
     // 配列内を探索ループ
     for (int i = 0; i < num; i++) {
      if (target == array[i]) {
        position = i + 1;
      }
     }

  ・探索結果の表示
   if (position == -1) {
    printf("探索対象数値はありませんでした\n");
   }
   else {
    printf("対象数値は%d番目にありました\n", position);
   }
    ループが完了した段階で、
    変数 position が -1 の場合、探索対象は見つかっておらず、
    変数 position が -1 以外の場合、探索成功で、
    この変数内にその位置(添え字 + 1)が格納されていますので、
    変数 position を確認し、その内容に合わせ表示します。

・実行してみます。
 上段メニュー"デバッグ(D)"のサブメニューより、
 "デバッグなしで開始(H)"を選択します。

デバッグ、実行指示画面
デバッグ、実行指示画面

・実行結果は、デバッグコンソール画面が開き表示されます。
 ※この画面は、何かのキーを打鍵することで閉じることができます。
 ※この実行では、探索値として 3 を入力し、
  1.最初に見つかった位置を探索位置とする場合として、
  最初の3の位置で、"3番目" と表示されます。

実行結果、デバッグコンソール画面1
実行結果、デバッグコンソール画面1

 ※この実行では、探索値として 3 を入力し、
  2.最後に見つかった位置を探索位置とする場合として、
  最後の3の位置で、"8番目" と表示されます。

実行結果、デバッグコンソール画面2
実行結果、デバッグコンソール画面2

 ※この実行では、探索値として 15 を入力し、
  配列内に対象数値がありませんので、
  "ありませんでした" と表示されます。

実行結果、デバッグコンソール画面3
実行結果、デバッグコンソール画面3

残りの、3.全ての位置を探索値とする場合の
プログラムをしてみます。

・プロジェクトを作成します。
 Visual Studio 2022を起動し、
 新しいプロジェクトを作成します。
 ・プロジェクトタイプ:"コンソールアプリ"
 ・プロジェクト名:"ct_105_2"
 とします。

・プログラム記述・編集画面が表示されるので、
 以下のプログラムを記述します。

プログラム記述後の編集画面2
プログラム記述後の編集画面2

 プログラムの記述内容

// 配列内より指定の値の有無を探索する_2

#include <iostream>

int main()
{
    // 変数宣言と初期化
    int array[] = { 1,2,3,4,5,6,7,3,9,10 };
    int target;
    int num;
    int position = -1;
    int quantity = 0;

    // キーボードからの探索数値を受け取る
    printf("探索数値:");
    scanf_s("%d", &target);

    // array配列の要素数を取得
    num = sizeof(array) / sizeof(array[0]);

    // 配列内を探索ループ
    for (int i = 0; i < num; i++) {
        if (target == array[i]) {
            position = i + 1;
            printf("%d番目 ", position);
            quantity += 1;
        }
    }

    // 探索結果の表示
    if (quantity == 0) {
        printf("探索対象数値はありませんでした\n");
    }
    else {
        printf("対象数値は%d個ありました\n", quantity);
    }

    return EXIT_SUCCESS;
}

 1つ目のプログラムとの変更点のみのプログラム解説です。

  ・変数宣言と初期化
   int quantity = 0;
    探索で見つかった個数を格納するための変数
    初期値は 0 (0個)としておきます。

  ・配列内を探索ループ
   for (int i = 0; i < num; i++) {
    if (target == array[i]) {
      position = i + 1;
      printf("%d番目 ", position);
      quantity += 1;
    }
   }
    見つかった場合、ループ時にその位置を画面表示します。
    また、見つかった数として、変数quantity を 1 カウントアップします。

  ・探索結果の表示
   if (quantity == 0) {
    printf("探索対象数値はありませんでした\n");
   }
   else {
    printf("対象数値は%d個ありました\n", quantity);
   }
    探索の成功失敗の判定を、変数 position から
    変数 quantity に変更し、見つかった個数で判断します。
    見つかった場合の位置は、探索ループで表示済みなので、
    見つかった数(変数 quantity)を表示するように変更してみました。

・実行してみます。
 上段メニュー"デバッグ(D)"のサブメニューより、
 "デバッグなしで開始(H)"を選択します。

・実行結果は、デバッグコンソール画面が開き表示されます。
 ※この実行では、3.全ての位置を探索値とする場合として、
  探索値として 3 を入力し場合で、
  "3番目" "8番目" "対象数値は2個ありました" と表示されます。
 ※この画面は、何かのキーを打鍵することで閉じることができます。

実行結果、デバッグコンソール画面4
実行結果、デバッグコンソール画面4