C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で配列内の最大3つの要素を検索する方法

この記事では、ソートされていない N 個の要素からなる配列 arr[] が与えられたときに、配列内で最も大きい3つの要素を見つける方法を解説します。

問題の例

まず、具体例を使って問題を確認しましょう。

入力 : arr[] = {7, 3, 9, 12, 1}
出力 : 12, 9, 7

解決アプローチ

求めるのは「配列の中で最大の3つの要素を見つけて出力する」ことです。これを実現する方法は複数あります。

方法1:一度の走査で上位3要素を追跡する(O(n))

最大の3つの要素の値を保持するために、max、max2、max3 という3つの変数を用意し、すべて arr[0] で初期化します。

続いて、配列を先頭から末尾まで走査しながら、各要素に対して以下の判定を行います。

  • if (arr[i] > max) → max3 = max2、max2 = max、max = arr[i]
  • else if (arr[i] > max2) → max3 = max2、max2 = arr[i]
  • else if (arr[i] > max3) → max3 = arr[i]

ループが終了した時点で、3つの変数に格納された値を出力します。

この方法のメリットは、配列をたった1回の走査(O(n))で処理できる点です。追加のメモリも定数個の変数だけで済むため、大規模な配列でも効率的に動作します。

サンプルプログラム(方法1)

#include <iostream>
using namespace std;
void findThreeLargestElements(int arr[], int arr_size){
    int max, max2, max3;
    max3 = max = max2 = arr[0];
    for(int i = 0; i < arr_size; i++){
        if (arr[i] > max){
            max3 = max2;
            max2 = max;
            max = arr[i];
        }
        else if (arr[i] > max2){
            max3 = max2;
            max2 = arr[i];
        }
        else if (arr[i] > max3)
            max3 = arr[i];
    }
    cout<<endl<<"Three largest elements of the array are "<<max<<", "<<max2<<", "<<max3;
}
int main(){
    int arr[] = {15, 2, 7, 86, 0, 21, 50};
    int n = sizeof(arr) / sizeof(arr[0]); 
    cout<<"The array is : ";
    for(int i = 0; i < n; i++) 
        cout<<arr[i]<<"\t"; 
    findThreeLargestElements(arr, n);
    return 0;
}

実行結果

The array is : 15 2 7 86 0 21 50
Three largest elements of the array are 86, 50, 21

方法2:ソートを利用する(O(n log n))

もうひとつのシンプルな解決策は、配列を降順にソートしてから、先頭の3つの要素を出力する方法です。降順ソート後の先頭3要素が、そのまま配列内で最大の3つの要素になります。

アルゴリズム

  • ステップ1 − ソートアルゴリズムを使って配列を降順にソートします。
  • ステップ2 − 先頭の3つの要素 arr[0]arr[1]arr[2] を出力します。

なお、重複した値を除外したい場合は、直前の出力値と比較しながら異なる値だけを3つ出力するとよいでしょう。

サンプルプログラム(方法2)

#include <bits/stdc++.h>
using namespace std;
void findThreeLargestElements(int arr[], int n){
    sort(arr, arr + n, std::greater<>());
    int j = 0;
    cout<<"\nThree largest elements are ";
    for(int i = 0; i < n; i++){ 
        if(arr[i] != arr[i+1]){ 
            cout<<arr[i]<<" "; 
            j++;
        }
        if(j == 3){
            break;
        }
    }
}
int main(){
    int arr[] = {15, 2, 7, 86, 0, 21, 50, 53, 50};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout<<"The array is : ";
    for(int i = 0; i < n; i++)
        cout<<arr[i]<<"\t";
    findThreeLargestElements(arr, n);
    return 0;
}

実行結果

The array is : 15 2 7 86 0 21 50 53 50
Three largest elements are 86 53 50

まとめ

方法時間計算量特徴
方法1:走査しながら追跡O(n)高速。大きな配列に最適
方法2:ソートを利用O(n log n)実装がシンプルで分かりやすい

パフォーマンスを重視する場合は方法1を、コードの簡潔さを優先する場合は方法2を選ぶとよいでしょう。

  1. C++で配列内の最小値・2番目・3番目に小さい要素を効率的に見つける方法

    n個の要素からなる配列が与えられたとき、その中から「1番目(最小)」「2番目」「3番目」に小さい要素を求めることを考えます。ここで、1番目の最小値は配列全体の最小値、2番目の最小値は1番目より大きい値の中で最も小さいもの、3番目の最小値は2番目より大きい値の中で最も小さいものを指します。この問題は、配列を一度だけ走査しながら、各要素について「1番目・2番目・3番目の最小値」の条件を順に判定していくことで解くことができます。アルゴリズムの考え方まず、1番目・2番目・3番目の最小値を表す変数 first、sec、third を用意し、それぞれ int 型の最大値 INT_MAX で初期化します。次

  2. C++で配列の最大要素とその位置を見つける方法

    配列の最大要素とは配列には複数の要素が格納されており、その中で他のすべての要素よりも大きい値を持つものが「最大要素」です。具体例51724上記の配列の場合、最大要素は7であり、インデックス2の位置に存在します。それでは、配列の最大要素を求めるC++プログラムを見ていきましょう。サンプルコード#include <iostream> using namespace std; int main() { int a[] = {4, 9, 1, 3, 8}; int largest, i, pos; largest = a[0]; for(i=1; i<