【初心者向け】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);

このオーバーロードは、firstlast で指定された範囲内のすべての要素を削除します。

  • last: 削除範囲の最後の要素の次の要素を指すイテレータ。
  • first: 削除範囲の最初の要素を指すイテレータ。


std::string str = "Hello, World!";

// "World" を削除
str.erase(str.find('W'), str.find('!') + 1);

// 結果: "Hello, "

戻り値

すべてのオーバーロードは、削除操作が完了した後に更新された文字列へのイテレータを返します。

  • 削除する要素が存在しない場合は、erase 関数は何も変更せず、元のイテレータを返します。
  • 範囲を削除する場合、firstlast より前に位置する必要があります。
  • 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::removestd::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 またはイテレータによる直接操作が適切です。より複雑な条件に基づいた削除が必要な場合は、アルゴリズムライブラリ、正規表現ライブラリ、またはカスタム関数を使用することができます。

  • 保守性: 将来的に変更が必要になった場合に、コードを簡単に更新できるようにする必要があります。
  • 読みやすさ: コードは、他の開発者が理解しやすいように、読みやすく記述する必要があります。
  • パフォーマンス: 処理する文字列の長さに応じて、パフォーマンスが重要な要素となる場合があります。