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

C++でvectorから部分ベクトル(サブベクトル)を抽出する方法

C++では、元の std::vector の一部を切り出して、新しいvector(部分ベクトル)を作成できます。本記事では、イテレータと範囲コンストラクタを活用して、指定した開始位置・終了位置の要素を取り出す方法を、アルゴリズムとサンプルコード、実行結果とともにわかりやすく解説します。

アルゴリズム

Begin
  開始位置 m と終了位置 n を引数に取る関数
  s(vector const &v, int m, int n) を宣言する。
    auto first = v.begin() + m;(m番目の要素を指すイテレータ)
    auto last = v.begin() + n + 1;(n番目の次の要素を指すイテレータ)
    vector型の変数を宣言し、first と last を渡して
    範囲内の要素で初期化する。
    作成した vector を返す。
  テンプレート型 T を宣言する。
  関数 show() を宣言する。
    vector v を引数として受け取る。
    for (auto i : v) で各要素 i の値を出力する。
  vector v を宣言し、初期値を設定する。
  変数 a = 3、b = 6 を初期化する。
  「Sub vector is:」というメッセージを出力する。
  別のvector sub_vector を宣言する。
    sub_vector = s(v, a, b) として、開始位置と終了位置を
    指定して部分ベクトルを初期化する。
  show() 関数を呼び出して sub_vector の値を表示する。
End.

サンプルコード

#include <iostream>
#include <vector>
using namespace std;
template<typename T>
vector<T> s(vector<T> const &v, int m, int n) {
   auto first = v.begin() + m;
   auto last = v.begin() + n + 1;
   vector<T> vector(first, last);
   return vector;
}
template<typename T>
void show(vector<T> const &v) {
   for (auto i: v) {
      cout << i << ' ';
   }
   cout << '\n';
}
int main() {
   vector<int> v = {7,6,2,4,1 ,9,10,15,17};
   int a = 3, b = 6;
   cout<<"Sub vector is:"<<endl;
   vector<int> sub_vector = s(v, a, b);
   show(sub_vector);
   return 0;
}

実行結果

Sub vector is:
4 1 9 10

コードのポイント

このプログラムの動作を理解するうえで重要な点は以下の通りです。

  • イテレータによる範囲指定: v.begin() + m はインデックス m の要素を指すイテレータです。同様に v.begin() + n + 1 はインデックス n の次の要素を指します。
  • 半開区間の扱い: STLの範囲は一般的に [first, last) という半開区間で表されます。そのため、インデックス n の要素まで含めたい場合は n + 1 を指定する必要があります。
  • 範囲コンストラクタ: vector<T> vector(first, last) により、イテレータが示す範囲の要素が新しいvectorにコピーされます。
  • 元のvectorは変更されない: 引数は const 参照で受け取っているため、元のvectorの内容は一切書き換えられず、安全に部分ベクトルだけを取り出せます。

上記の例では、{7, 6, 2, 4, 1, 9, 10, 15, 17} というvectorから、インデックス3〜6の要素(4, 1, 9, 10)が抽出され、新しいvectorとして出力されています。

  1. C++のvector::resize()とvector::reserve()の違いとは?使い方を徹底解説

    std::vectorは動的配列と同じように、要素の挿入や削除が行われるたびにサイズを自動的に調整できるコンテナで、ストレージの管理はvector自身が担います。 vector::resize()とvector::reserve()の最も大きな違いは、resize()はベクターのサイズ(要素数)を実際に変更するのに対し、reserve()はサイズをまったく変更しないという点です。reserve()は「少なくとも指定した個数の要素を、メモリの再割り当てなしで格納できるようにする」ためだけに使われます。一方、resize()では指定した値が現在の要素数より小さい場合、メモリが縮小され余分な領域は

  2. C++の型推論とは?autoキーワードの基本と使い方をわかりやすく解説

    型推論(Type Inference)とは、プログラミング言語において式のデータ型を自動的に判別する機能のことです。この機能は、強い静的型付けを持つ一部の言語に備わっています。 C++では、C++11で追加されたautoキーワードを使うことで、自動的な型推論が可能になります。これにより、開発者は複雑な型名を明示的に書く必要がなくなり、コードがシンプルで読みやすくなります。 autoキーワードの活用例 たとえば、vectorの要素を走査するイテレータを作成したい場合、従来は std::vector<int>::iterator という長い型名を記述する必要がありました。しかし、aut