Menu
Coddy logo textTech

STLアルゴリズム

CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 73/104。

STLのアルゴリズムは、イテレータによって定義された範囲に対して動作するテンプレート関数です。これらは <algorithm> および <numeric> ヘッダーに含まれており、互換性のあるイテレータを提供する任意のコンテナで使用できます。

std::sort はデフォルトで要素を昇順に並べ替えます:

#include <algorithm>
#include <vector>

std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end());
// nums: {1, 2, 5, 8}

std::find は値を検索し、最初に見つかった要素へのイテレータを返します。見つからない場合は end() を返します:

auto it = std::find(nums.begin(), nums.end(), 5);
if (it != nums.end()) {
    std::cout << "Found at index: " << (it - nums.begin());
}

std::transform は各要素に操作を適用し、その結果をコピー先の範囲に格納します:

std::vector<int> doubled(nums.size());
std::transform(nums.begin(), nums.end(), doubled.begin(),
               [](int x) { return x * 2; });
// doubled: {2, 4, 10, 16}

<numeric> ヘッダーの std::accumulate は、すべての要素を1つの値にまとめます:

#include <numeric>

int sum = std::accumulate(nums.begin(), nums.end(), 0);
// 合計: 16 (1 + 2 + 5 + 8)

これらのアルゴリズムは、コンテナを直接受け取るのではなくイテレータの範囲を受け取ります。これにより、同じコードで部分的な範囲や異なるコンテナ型に対して動作できる柔軟性が備わっています。

challenge icon

チャレンジ

簡単

STLアルゴリズムを使用して数値のコレクションを処理するスコアアナライザーを構築しましょう。sortfindtransform、およびaccumulateがどのように連携してデータを分析するかを示すユーティリティ関数を作成します。

コードは2つのファイルに分けて構成します:

  • ScoreAnalyzer.h: 整数のベクトルを処理するためにSTLアルゴリズムを使用するユーティリティ関数を定義します。

    std::vector<int>&を受け取り、std::sortを使用して昇順にソートするsortScoresという関数を作成してください。

    const std::vector<int>&とターゲットとなるint値を受け取るfindScoreという関数を作成してください。std::findを使用してターゲットを検索します。見つかった場合は、インデックス(開始位置からの距離)を返します。見つからない場合は、-1を返します。

    const std::vector<int>&とボーナス額のintを受け取るapplyBonusという関数を作成してください。std::transformを使用して、各スコアにボーナスが加算された新しいベクトルを作成して返します。

    const std::vector<int>&を受け取り、平均をdoubleとして返すcalculateAverageという関数を作成してください。std::accumulateを使用して合計を計算し、サイズで割ります。

    const std::vector<int>&を受け取り、すべての要素をスペースで区切って出力し、最後に改行を出力するprintVectorという関数を作成してください。

  • main.cpp: 6つの入力(それぞれ別の行)を読み込みます:
    1. 1つ目のスコア(整数)
    2. 2つ目のスコア(整数)
    3. 3つ目のスコア(整数)
    4. 4つ目のスコア(整数)
    5. 検索するスコア(整数)
    6. 適用するボーナス額(整数)

    4つのスコアでベクトルを作成し、アルゴリズムを実演します:

    1. Original: に続いてベクトルの内容を表示します
    2. スコアをソートし、Sorted: に続いてソートされたベクトルを表示します
    3. ソートされたベクトル内でターゲットスコアを検索します。見つかった場合は、Found <value> at index <index>と表示します。見つからない場合は、<value> not foundと表示します
    4. ソートされたスコアにボーナスを適用し、With bonus: に続いて新しいベクトルを表示します
    5. 元のソートされたスコア(ボーナス適用前)の平均を計算し、Average: <value>として小数点以下1桁で表示します

例えば、入力が 75, 90, 60, 85, 85, 5 の場合:

Original: 75 90 60 85 
Sorted: 60 75 85 90 
Found 85 at index 2
With bonus: 65 80 90 95 
Average: 77.5

入力が 100, 80, 95, 70, 50, 10 の場合:

Original: 100 80 95 70 
Sorted: 70 80 95 100 
50 not found
With bonus: 80 90 105 110 
Average: 86.2

sortfindtransformには<algorithm>を、accumulateには<numeric>をインクルードすることを忘れないでください。平均の書式設定には、<iomanip>std::fixedstd::setprecision(1)を使用してください。

チートシート

STLアルゴリズムは、イテレータによって定義された範囲に対して動作する、<algorithm>および<numeric>のテンプレート関数です。

std::sortは、要素を昇順に並べ替えます:

#include <algorithm>
#include <vector>

std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end());
// nums: {1, 2, 5, 8}

std::findは値を検索し、最初に見つかった要素へのイテレータを返します。見つからない場合はend()を返します:

auto it = std::find(nums.begin(), nums.end(), 5);
if (it != nums.end()) {
    std::cout << "Found at index: " << (it - nums.begin());
}

std::transformは、各要素に操作を適用し、その結果をデスティネーション範囲に格納します:

std::vector<int> doubled(nums.size());
std::transform(nums.begin(), nums.end(), doubled.begin(),
               [](int x) { return x * 2; });
// doubled: {2, 4, 10, 16}

<numeric>std::accumulateは、すべての要素を1つの値にまとめます:

#include <numeric>

int sum = std::accumulate(nums.begin(), nums.end(), 0);
// sum: 16 (1 + 2 + 5 + 8)

これらのアルゴリズムはイテレータの範囲で動作するため、部分的な範囲や異なるコンテナタイプに対して柔軟に使用できます。

自分で試してみよう

#include <iostream>
#include <vector>
#include <iomanip>
#include "ScoreAnalyzer.h"

using namespace std;

int main() {
    // 6つの入力を読み込む
    int score1, score2, score3, score4;
    int searchTarget, bonusAmount;
    
    cin >> score1;
    cin >> score2;
    cin >> score3;
    cin >> score4;
    cin >> searchTarget;
    cin >> bonusAmount;
    
    // TODO: 4つのスコアを持つ vector を作成する
    
    // TODO: "Original:" に続いて vector の内容を表示する
    
    // TODO: スコアをソートし、"Sorted:" に続いてソートされた vector を表示する
    
    // TODO: ソートされた vector 内で検索対象のスコアを検索する
    // 見つかった場合、"Found <value> at index <index>" と表示する
    // 見つからない場合、"<value> not found" と表示する
    
    // TODO: ソートされたスコアにボーナスを適用し、"With bonus:" に続いて新しい vector を表示する
    
    // TODO: ソートされたスコア(ボーナス適用前)の平均を計算して表示する
    // 書式設定に fixed と setprecision(1) を使用する
    // "Average: <value>" として表示する
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン