[C++] std::string内で特定文字列を検索し個数をカウントする方法
C++で文字列操作を行う際、std::string
内で特定の文字列を検索し、その出現回数をカウントする方法があります。
この操作は、std::string::find
メソッドを使用して実現できます。
このメソッドは、指定した文字列が見つかった位置を返し、見つからない場合はstd::string::npos
を返します。
ループを使用して文字列全体を検索し、見つかった位置を基に次の検索を開始することで、特定の文字列の出現回数をカウントできます。
- std::stringを用いた特定文字列の検索方法
- 文字列の出現回数をカウントするためのさまざまな手法
- 大文字小文字を区別しない検索の実現方法
- 複数の文字列を同時にカウントする方法
- 文字列の出現位置を記録するテクニック
特定文字列の検索方法
std::string
を用いて文字列内で特定の文字列を検索するための便利なメソッドがいくつか提供されています。
ここでは、代表的なメソッドについて解説します。
findメソッドの使い方
findメソッド
は、文字列内で特定の文字列を検索し、その最初の位置を返します。
見つからない場合はstd::string::npos
を返します。
#include <iostream>
#include <string>
int main() {
std::string text = "C++プログラミングは楽しいです。";
std::string keyword = "プログラミング";
// 文字列内で"プログラミング"を検索
size_t position = text.find(keyword);
if (position != std::string::npos) {
std::cout << "見つかりました: 位置 " << position << std::endl;
} else {
std::cout << "見つかりませんでした。" << std::endl;
}
return 0;
}
見つかりました: 位置 3
この例では、text
内で"プログラミング"
を検索し、その開始位置を出力しています。
rfindメソッドの使い方
rfindメソッド
は、文字列内で特定の文字列を逆方向(末尾から先頭)に検索し、その最初の位置を返します。
#include <iostream>
#include <string>
int main() {
std::string text = "C++プログラミングは楽しいです。プログラミングは面白いです。";
std::string keyword = "プログラミング";
// 文字列内で"プログラミング"を逆方向に検索
size_t position = text.rfind(keyword);
if (position != std::string::npos) {
std::cout << "最後に見つかりました: 位置 " << position << std::endl;
} else {
std::cout << "見つかりませんでした。" << std::endl;
}
return 0;
}
最後に見つかりました: 位置 18
この例では、text
内で"プログラミング"
を末尾から検索し、その開始位置を出力しています。
find_first_ofとfind_last_ofの違い
find_first_of
とfind_last_of
は、指定した文字集合の中で最初または最後に見つかる文字の位置を返します。
#include <iostream>
#include <string>
int main() {
std::string text = "C++プログラミング";
std::string characters = "プラ";
// 最初に見つかる文字を検索
size_t first_position = text.find_first_of(characters);
// 最後に見つかる文字を検索
size_t last_position = text.find_last_of(characters);
std::cout << "最初に見つかる文字の位置: " << first_position << std::endl;
std::cout << "最後に見つかる文字の位置: " << last_position << std::endl;
return 0;
}
最初に見つかる文字の位置: 3
最後に見つかる文字の位置: 5
この例では、text
内で"プラ"
のいずれかの文字が最初と最後に見つかる位置を出力しています。
find_first_not_ofとfind_last_not_ofの使い方
find_first_not_of
とfind_last_not_of
は、指定した文字集合に含まれない最初または最後の文字の位置を返します。
#include <iostream>
#include <string>
int main() {
std::string text = "C++プログラミング";
std::string characters = "C+";
// 最初に見つからない文字を検索
size_t first_not_position = text.find_first_not_of(characters);
// 最後に見つからない文字を検索
size_t last_not_position = text.find_last_not_of(characters);
std::cout << "最初に見つからない文字の位置: " << first_not_position << std::endl;
std::cout << "最後に見つからない文字の位置: " << last_not_position << std::endl;
return 0;
}
最初に見つからない文字の位置: 3
最後に見つからない文字の位置: 9
この例では、text
内で"C+"
に含まれない最初と最後の文字の位置を出力しています。
文字列のカウント方法
特定の文字列や文字の出現回数をカウントするためのさまざまな方法が提供されています。
ここでは、代表的な方法について解説します。
std::countの利用
std::count
は、指定した範囲内で特定の文字の出現回数をカウントするために使用されます。
<algorithm>
ヘッダーをインクルードする必要があります。
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string text = "C++プログラミングは楽しいです。";
char target = 'プ';
// 文字'プ'の出現回数をカウント
int count = std::count(text.begin(), text.end(), target);
std::cout << "文字'プ'の出現回数: " << count << std::endl;
return 0;
}
文字'プ'の出現回数: 1
この例では、text
内で文字'プ'
の出現回数をカウントし、その結果を出力しています。
ループを用いたカウント方法
ループを用いて、特定の文字列の出現回数をカウントする方法もあります。
これは、std::string::find
を利用して実装できます。
#include <iostream>
#include <string>
int main() {
std::string text = "C++プログラミングは楽しいです。プログラミングは面白いです。";
std::string keyword = "プログラミング";
size_t position = 0;
int count = 0;
// 文字列"プログラミング"の出現回数をカウント
while ((position = text.find(keyword, position)) != std::string::npos) {
++count;
position += keyword.length(); // 検索位置を更新
}
std::cout << "文字列'プログラミング'の出現回数: " << count << std::endl;
return 0;
}
文字列'プログラミング'の出現回数: 2
この例では、text
内で"プログラミング"
の出現回数をループを用いてカウントし、その結果を出力しています。
std::regexを用いたカウント方法
std::regex
を用いると、正規表現を使って文字列の出現回数をカウントすることができます。
<regex>
ヘッダーをインクルードする必要があります。
#include <iostream>
#include <string>
#include <regex>
int main() {
std::string text = "C++プログラミングは楽しいです。プログラミングは面白いです。";
std::regex pattern("プログラミング");
// 正規表現を用いて"プログラミング"の出現回数をカウント
auto words_begin = std::sregex_iterator(text.begin(), text.end(), pattern);
auto words_end = std::sregex_iterator();
int count = std::distance(words_begin, words_end);
std::cout << "文字列'プログラミング'の出現回数: " << count << std::endl;
return 0;
}
文字列'プログラミング'の出現回数: 2
この例では、text
内で正規表現を用いて"プログラミング"
の出現回数をカウントし、その結果を出力しています。
正規表現を使うことで、より柔軟なパターンマッチングが可能です。
応用例
文字列の検索やカウントは、さまざまな応用が可能です。
ここでは、いくつかの応用例を紹介します。
大文字小文字を区別しない検索
大文字小文字を区別せずに文字列を検索するには、文字列をすべて小文字または大文字に変換してから検索を行います。
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string text = "C++ Programming is Fun.";
std::string keyword = "programming";
// 文字列を小文字に変換
std::string lower_text = text;
std::transform(lower_text.begin(), lower_text.end(), lower_text.begin(), ::tolower);
// 検索キーワードも小文字に変換
std::string lower_keyword = keyword;
std::transform(lower_keyword.begin(), lower_keyword.end(), lower_keyword.begin(), ::tolower);
// 小文字に変換した文字列で検索
size_t position = lower_text.find(lower_keyword);
if (position != std::string::npos) {
std::cout << "見つかりました: 位置 " << position << std::endl;
} else {
std::cout << "見つかりませんでした。" << std::endl;
}
return 0;
}
見つかりました: 4
この例では、text
とkeyword
を小文字に変換してから検索を行い、大文字小文字を区別しない検索を実現しています。
複数の文字列を同時にカウントする方法
複数の文字列を同時にカウントするには、ループとマップを組み合わせて使用します。
#include <iostream>
#include <string>
#include <map>
int main() {
std::string text = "C++プログラミングは楽しいです。プログラミングは面白いです。";
std::map<std::string, int> keywords = {{"プログラミング", 0}, {"楽しい", 0}, {"面白い", 0}};
for (auto& [keyword, count] : keywords) {
size_t position = 0;
while ((position = text.find(keyword, position)) != std::string::npos) {
++count;
position += keyword.length();
}
}
for (const auto& [keyword, count] : keywords) {
std::cout << "文字列'" << keyword << "'の出現回数: " << count << std::endl;
}
return 0;
}
文字列'プログラミング'の出現回数: 2
文字列'楽しい'の出現回数: 1
文字列'面白い'の出現回数: 1
この例では、text
内で複数のキーワードの出現回数を同時にカウントし、その結果を出力しています。
特定の条件での文字列カウント
特定の条件で文字列をカウントするには、条件を満たすかどうかをチェックしながらカウントを行います。
#include <iostream>
#include <string>
int main() {
std::string text = "C++プログラミングは楽しいです。プログラミングは面白いです。";
std::string keyword = "プログラミング";
size_t position = 0;
int count = 0;
// 文字列"プログラミング"が文の先頭にある場合のみカウント
while ((position = text.find(keyword, position)) != std::string::npos) {
if (position == 0 || text[position - 1] == '。') {
++count;
}
position += keyword.length();
}
std::cout << "文の先頭にある'プログラミング'の出現回数: " << count << std::endl;
return 0;
}
文の先頭にある'プログラミング'の出現回数: 1
この例では、text
内で"プログラミング"
が文の先頭にある場合のみカウントしています。
文字列の出現位置を記録する方法
文字列の出現位置を記録するには、検索しながら位置をベクターに保存します。
#include <iostream>
#include <string>
#include <vector>
int main() {
std::string text = "C++プログラミングは楽しいです。プログラミングは面白いです。";
std::string keyword = "プログラミング";
size_t position = 0;
std::vector<size_t> positions;
// 文字列"プログラミング"の出現位置を記録
while ((position = text.find(keyword, position)) != std::string::npos) {
positions.push_back(position);
position += keyword.length();
}
std::cout << "文字列'プログラミング'の出現位置: ";
for (size_t pos : positions) {
std::cout << pos << " ";
}
std::cout << std::endl;
return 0;
}
文字列'プログラミング'の出現位置: 3 18
この例では、text
内で"プログラミング"
の出現位置をすべて記録し、その結果を出力しています。
よくある質問
まとめ
この記事では、std::string
を用いた特定文字列の検索とカウント方法について詳しく解説しました。
find
やrfind
といった基本的なメソッドから、std::regex
を用いた高度な検索方法まで、さまざまな手法を紹介しました。
これらの知識を活用して、より効率的な文字列操作を実現し、プログラムの精度を向上させてみてください。