【初心者向け】C++の「Strings」で文字列から要素を削除! `std::basic_string::erase` の使い方
位置と長さによる削除
std::basic_string& erase(size_type pos, size_type len);
このオーバーロードは、文字列内の pos
番目の位置から len
個の要素を削除します。
len
: 削除する要素の数。npos
を指定すると、pos
番目の位置以降のすべての要素が削除されます。pos
: 削除を開始する位置。文字列の先頭は0
であり、末尾はsize()
で表されます。
例
std::string str = "Hello, World!";
// "World!" を削除
str.erase(7, 5);
// 結果: "Hello, "
イテレータによる削除
iterator erase(iterator p);
このオーバーロードは、p
で指される要素を削除します。
p
: 削除する要素を指すイテレータ。
例
std::string str = "Hello, World!";
// 2番目の ',' を削除
str.erase(str.begin() + 5);
// 結果: "Hello World!"
イテレータ範囲による削除
iterator erase(iterator first, iterator last);
このオーバーロードは、first
と last
で指定された範囲内のすべての要素を削除します。
last
: 削除範囲の最後の要素の次の要素を指すイテレータ。first
: 削除範囲の最初の要素を指すイテレータ。
例
std::string str = "Hello, World!";
// "World" を削除
str.erase(str.find('W'), str.find('!') + 1);
// 結果: "Hello, "
戻り値
すべてのオーバーロードは、削除操作が完了した後に更新された文字列へのイテレータを返します。
- 削除する要素が存在しない場合は、
erase
関数は何も変更せず、元のイテレータを返します。 - 範囲を削除する場合、
first
はlast
より前に位置する必要があります。 erase
関数は、文字列の内容を変更するため、変更後の文字列にアクセスする前にイテレータとポインタを更新する必要があります。
特定の文字を削除
この例では、文字列内のすべての "a" 文字を削除します。
#include <iostream>
#include <string>
int main() {
std::string str = "abracadabra";
// 文字列内のすべての 'a' を削除
str.erase(std::remove(str.begin(), str.end(), 'a'), str.end());
std::cout << str << std::endl; // 結果: "brcdbr"
return 0;
}
空白文字で区切られた単語の最初の単語を削除
この例では、空白文字で区切られた単語の最初の単語を削除します。
#include <iostream>
#include <string>
int main() {
std::string str = "Hello World!";
// 最初の空白文字までの部分を削除
str.erase(str.find(' '));
std::cout << str << std::endl; // 結果: "World!"
return 0;
}
サブストリングを削除
この例では、文字列内の特定のサブストリングを削除します。
#include <iostream>
#include <string>
int main() {
std::string str = "This is a test string";
// "is a " 部分を削除
str.erase(str.find("is a "), 5);
std::cout << str << std::endl; // 結果: "This test string"
return 0;
}
イテレータによる直接操作
std::string str = "Hello, World!";
// 2番目の ',' を削除
str.erase(str.begin() + 5);
// 結果: "Hello World!"
この方法は、単純な削除操作には効率的ですが、範囲の削除や複雑な条件に基づいた削除には適していません。
利点
- 効率的
- シンプルで分かりやすい
欠点
- 範囲の削除や複雑な条件に基づいた削除には不向き
アルゴリズムライブラリの使用
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string str = "Hello, World!";
// 文字列内のすべての 'a' を削除
std::erase(str.begin(), str.end(), 'a');
std::cout << str << std::endl; // 結果: "Hll, Wrd!"
return 0;
}
std::remove
や std::remove_if
などのアルゴリズム関数を使用して、特定の条件に基づいて要素を削除することができます。
利点
- 複雑な条件に基づいた削除が可能
- 柔軟性が高い
欠点
std::basic_string::erase
よりも冗長になる場合がある
正規表現ライブラリの使用
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string str = "Hello, World!";
// 最初の空白文字までの部分を削除
std::regex re("\\s+");
std::string result = std::regex_replace(str, re, "");
std::cout << result << std::endl; // 結果: "World!"
return 0;
}
正規表現を使用して、パターンに一致する部分を削除することができます。
利点
- 複雑なパターンのマッチングが可能
欠点
- パフォーマンスが遅い場合がある
- 正規表現ライブラリの使用方法を理解する必要がある
カスタム関数を使用する
#include <iostream>
#include <string>
bool is_vowel(char c) {
return strchr("aeiouAEIOU", c) != nullptr;
}
int main() {
std::string str = "Hello, World!";
// 文字列内のすべての母音を削除
for (size_t i = 0; i < str.size(); ++i) {
if (is_vowel(str[i])) {
str.erase(i, 1);
--i;
}
}
std::cout << str << std::endl; // 結果: "Hll, Wrd!"
return 0;
}
特定の条件に基づいて要素を削除する必要がある場合は、カスタム関数を作成することができます。
利点
- 完全な制御が可能
欠点
- テストが必要
- コードが冗長になる場合がある
どの代替方法が最適かは、具体的な状況によって異なります。シンプルな削除操作であれば、std::basic_string::erase
またはイテレータによる直接操作が適切です。より複雑な条件に基づいた削除が必要な場合は、アルゴリズムライブラリ、正規表現ライブラリ、またはカスタム関数を使用することができます。
- 保守性: 将来的に変更が必要になった場合に、コードを簡単に更新できるようにする必要があります。
- 読みやすさ: コードは、他の開発者が理解しやすいように、読みやすく記述する必要があります。
- パフォーマンス: 処理する文字列の長さに応じて、パフォーマンスが重要な要素となる場合があります。