[C++] vectorへの要素追加と削除の方法
C++のvector
に要素を追加するには、push_back()メソッド
を使用します。
これは、指定した要素をベクターの末尾に追加します。
また、emplace_back()
を使うと、要素を直接構築しながら追加できます。
要素を削除するには、pop_back()メソッド
を使用して末尾の要素を削除します。
特定の位置の要素を削除するには、erase()メソッド
を使います。
erase()
は、イテレータを引数に取り、その位置の要素を削除します。
範囲を指定して削除することも可能です。
clear()メソッド
を使うと、ベクター内のすべての要素を削除できます。
vectorへの要素追加方法
C++のstd::vector
は、動的配列として非常に便利なコンテナです。
ここでは、vector
に要素を追加するためのさまざまな方法について解説します。
push_back()メソッドの使い方
push_back()メソッド
は、vector
の末尾に新しい要素を追加するための最も基本的な方法です。
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers; // 整数型のvectorを宣言
numbers.push_back(10); // 10を追加
numbers.push_back(20); // 20を追加
numbers.push_back(30); // 30を追加
for (int num : numbers) {
std::cout << num << " "; // 各要素を出力
}
return 0;
}
10 20 30
push_back()
は、要素を追加するたびにvector
のサイズを自動的に増やします。
これにより、手動でサイズを管理する必要がありません。
emplace_back()メソッドの使い方
emplace_back()メソッド
は、push_back()
と似ていますが、オブジェクトを直接構築するための引数を受け取ることができます。
これにより、オブジェクトのコピーを避けることができ、パフォーマンスが向上する場合があります。
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> words; // 文字列型のvectorを宣言
words.emplace_back("こんにちは"); // "こんにちは"を追加
words.emplace_back("世界"); // "世界"を追加
for (const std::string& word : words) {
std::cout << word << " "; // 各要素を出力
}
return 0;
}
こんにちは 世界
emplace_back()
は、コンストラクタの引数を直接渡すことができるため、オブジェクトの構築が効率的に行われます。
insert()メソッドでの要素追加
insert()メソッド
は、vector
の任意の位置に要素を追加することができます。
これにより、特定の位置に要素を挿入することが可能です。
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30}; // 初期化されたvector
auto it = numbers.begin(); // イテレータを取得
numbers.insert(it + 1, 15); // 2番目の位置に15を挿入
for (int num : numbers) {
std::cout << num << " "; // 各要素を出力
}
return 0;
}
10 15 20 30
insert()
を使用すると、指定した位置に要素を挿入でき、既存の要素は後ろにシフトされます。
reserve()メソッドでの容量確保
reserve()メソッド
は、vector
の容量を事前に確保するために使用されます。
これにより、要素追加時のメモリ再配置を減らし、パフォーマンスを向上させることができます。
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers; // 整数型のvectorを宣言
numbers.reserve(5); // 5つの要素分の容量を確保
numbers.push_back(10); // 10を追加
numbers.push_back(20); // 20を追加
std::cout << "容量: " << numbers.capacity() << std::endl; // 現在の容量を出力
return 0;
}
容量: 5
reserve()
を使用することで、vector
の容量を事前に設定し、頻繁なメモリ再配置を避けることができます。
これにより、特に大量の要素を追加する場合にパフォーマンスが向上します。
vectorからの要素削除方法
C++のstd::vector
では、要素を削除するためのさまざまな方法が用意されています。
ここでは、vector
から要素を削除するための基本的なメソッドについて解説します。
pop_back()メソッドの使い方
pop_back()メソッド
は、vector
の末尾にある要素を削除します。
このメソッドは、削除する要素を指定する必要がないため、最も簡単な削除方法の一つです。
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30}; // 初期化されたvector
numbers.pop_back(); // 末尾の要素を削除
for (int num : numbers) {
std::cout << num << " "; // 各要素を出力
}
return 0;
}
10 20
pop_back()
は、vector
の末尾の要素を削除するため、サイズが1減少しますが、容量は変わりません。
erase()メソッドでの要素削除
erase()メソッド
は、vector
の任意の位置にある要素を削除することができます。
これにより、特定の要素や範囲を削除することが可能です。
単一要素の削除
単一の要素を削除する場合、削除したい要素のイテレータを指定します。
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30, 40}; // 初期化されたvector
auto it = numbers.begin(); // イテレータを取得
numbers.erase(it + 1); // 2番目の要素を削除
for (int num : numbers) {
std::cout << num << " "; // 各要素を出力
}
return 0;
}
10 30 40
erase()
を使用すると、指定した位置の要素が削除され、後続の要素が前にシフトされます。
範囲指定での削除
範囲を指定して削除する場合、開始位置と終了位置のイテレータを指定します。
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30, 40, 50}; // 初期化されたvector
auto start = numbers.begin() + 1; // 開始位置のイテレータ
auto end = numbers.begin() + 4; // 終了位置のイテレータ
numbers.erase(start, end); // 2番目から4番目の要素を削除
for (int num : numbers) {
std::cout << num << " "; // 各要素を出力
}
return 0;
}
10 50
範囲指定でerase()
を使用すると、指定した範囲内の要素がすべて削除されます。
clear()メソッドでの全要素削除
clear()メソッド
は、vector
内のすべての要素を削除します。
これにより、vector
は空になりますが、容量はそのまま保持されます。
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30}; // 初期化されたvector
numbers.clear(); // 全要素を削除
std::cout << "サイズ: " << numbers.size() << std::endl; // 現在のサイズを出力
return 0;
}
サイズ: 0
clear()
を使用すると、vector
のサイズが0になり、すべての要素が削除されますが、メモリの容量は解放されません。
vectorの要素追加と削除の注意点
C++のstd::vector
は便利なコンテナですが、要素の追加や削除に伴ういくつかの注意点があります。
これらを理解することで、より効率的にvector
を使用することができます。
メモリ再配置の影響
vector
は動的にサイズを変更できるため、要素を追加する際にメモリの再配置が発生することがあります。
再配置が発生すると、以下のような影響があります。
- パフォーマンスの低下: 再配置は新しいメモリ領域を確保し、既存の要素をコピーするため、時間がかかります。
- ポインタやイテレータの無効化: 再配置が発生すると、以前のメモリ領域に対するポインタやイテレータは無効になります。
再配置を最小限に抑えるためには、reserve()メソッド
を使用して事前に必要な容量を確保することが推奨されます。
イテレータの無効化
vector
の要素を追加または削除すると、イテレータが無効化されることがあります。
特に、以下の操作でイテレータが無効化される可能性があります。
- 要素の追加:
push_back()
やinsert()
で再配置が発生した場合、すべてのイテレータが無効になります。 - 要素の削除:
erase()
やpop_back()
を使用すると、削除された要素以降のイテレータが無効になります。
無効化されたイテレータを使用すると、未定義の動作を引き起こす可能性があるため、イテレータを再取得することが重要です。
パフォーマンスへの影響
vector
の要素追加と削除は、パフォーマンスに影響を与えることがあります。
以下の点に注意することで、パフォーマンスを最適化できます。
- 追加時の再配置: 頻繁な再配置を避けるために、
reserve()
を使用して必要な容量を事前に確保します。 - 削除時のシフト操作:
erase()
で要素を削除すると、後続の要素がシフトされるため、削除操作が多い場合はstd::list
などの他のコンテナを検討することも一案です。 - メモリの効率的な使用:
shrink_to_fit()
メソッドを使用して、不要なメモリを解放することができますが、これは必ずしもメモリを解放することを保証するものではありません。
これらの注意点を理解し、適切に対処することで、vector
をより効率的に使用することができます。
vectorの応用例
C++のstd::vector
は、柔軟で強力なコンテナであり、さまざまな用途に応用することができます。
ここでは、vector
の代表的な応用例について解説します。
動的配列としての利用
vector
は、動的にサイズを変更できる配列として利用できます。
配列のサイズが事前にわからない場合や、要素の追加・削除が頻繁に行われる場合に便利です。
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers; // 動的配列としてのvector
for (int i = 0; i < 5; ++i) {
numbers.push_back(i * 10); // 要素を追加
}
for (int num : numbers) {
std::cout << num << " "; // 各要素を出力
}
return 0;
}
0 10 20 30 40
この例では、vector
を動的配列として使用し、要素を追加しています。
vector
はサイズを自動的に調整するため、配列のサイズを事前に決定する必要がありません。
スタックとしての利用
vector
は、LIFO(Last In, First Out)構造のスタックとしても利用できます。
push_back()
で要素を追加し、pop_back()
で要素を削除することで、スタックの操作を実現できます。
#include <iostream>
#include <vector>
int main() {
std::vector<int> stack; // スタックとしてのvector
stack.push_back(10); // 要素を追加
stack.push_back(20);
stack.push_back(30);
while (!stack.empty()) {
std::cout << stack.back() << " "; // 末尾の要素を出力
stack.pop_back(); // 末尾の要素を削除
}
return 0;
}
30 20 10
この例では、vector
をスタックとして使用し、要素を追加および削除しています。
back()メソッド
で末尾の要素を取得し、pop_back()
で削除することで、スタックの動作を模倣しています。
キューとしての利用
vector
は、FIFO(First In, First Out)構造のキューとしても利用できます。
push_back()
で要素を追加し、erase()
で先頭の要素を削除することで、キューの操作を実現できます。
#include <iostream>
#include <vector>
int main() {
std::vector<int> queue; // キューとしてのvector
queue.push_back(10); // 要素を追加
queue.push_back(20);
queue.push_back(30);
while (!queue.empty()) {
std::cout << queue.front() << " "; // 先頭の要素を出力
queue.erase(queue.begin()); // 先頭の要素を削除
}
return 0;
}
10 20 30
この例では、vector
をキューとして使用し、要素を追加および削除しています。
front()メソッド
で先頭の要素を取得し、erase()
で削除することで、キューの動作を模倣しています。
これらの応用例を通じて、vector
の柔軟性と多様な用途を理解することができます。
用途に応じて適切な操作を選択することで、効率的なプログラムを作成することが可能です。
まとめ
この記事では、C++のstd::vector
における要素の追加と削除の方法について詳しく解説しました。
vector
の基本的な操作から応用例までを通じて、その柔軟性と利便性を確認できたことでしょう。
これを機に、vector
を活用したプログラムを実際に作成し、さらなるスキルアップを目指してみてください。