C++ 文字列型で前方一致の検索【std::string startsWith/hasPrefix 接頭辞判定】

C++の文字列クラスstd::stringには、接頭辞(プレフィックス)を検索するためのメソッドとしてstartsWithhasPrefixが定義されていません。指定の文字列が特定の文字列で始まるかどうかを判定したい場合には、std::equal関数やfindメンバ関数やcompareメンバ関数による代用が必要です。

目次

スポンサーリンク

前方一致(prefix search, starts with)

std::equal関数による判定

std::string型文字列に対して、先頭文字列の一致を判定するためには、std::equal関数による比較がもっとも効率的です。

// #include <algorithm> // std::equal

std::string s = "abc"; // 検索先の文字列
std::string t = "ab";  // 検索文字列
if (s.size() >= t.size() &&
    std::equal(std::begin(t), std::end(t), std::begin(s))) {
   puts("文字列`ab`で始まる文字列です");
}

C言語スタイルの文字列による検索を行う場合には、若干の改変が必要となります。

std::string s = "abc";
const char* t = "ab"; // 検索文字列(文字列ポインタ)
size_t n = std::char_traits<char>::length(t); // 検索文字列の長さ
if (s.size() >= n && std::equal(t, t + n, std::begin(s))) {
   puts("文字列`ab`で始まる文字列です");
}
参考: std::equal関数

findメンバ関数による判定

先頭文字列の一致を判定するためには、findメンバ関数の利用がもっとも手っ取り早い方法ですが、長文検索時の処理効率はあまり良くありません。

std::string s = "abc";

if (s.find("ab") == 0) {
   puts("文字列`ab`で始まる文字列です");
}

// char型の文字を検索することも可能
if (s.find('a') == 0) puts("文字`a`で始まる文字列です");

findメンバ関数は一致する文字列が見つかるまで全文を検索するため、先頭文字列が一致しなかった場合でも、文字列の末尾まで余計な検索が行われてしまうことになります。

参考: findメンバ関数

compareメンバ関数による判定

findメンバ関数は全文検索が発生する場合があるため、より効率的な処理を求める場合には、検索開始位置と終了位置の指定が可能なcompareメンバ関数への置き換えが有効です。

std::string s = "abc";
std::string t = "ab";

if (s.size() >= t.size() &&
    s.compare(0, t.size(), t) == 0) {
   puts("文字列`ab`で始まる文字列です");
}

ただし、compareメンバ関数は検索文字列の大小比較を伴うため、より処理効率の高いプログラムを求める場合には、冒頭で説明した「# std::equal関数による判定」による比較テクニックの利用が必要となります。

参考: compare メンバ関数

文字/文字集合による判定

char型の文字を検索する場合は添字アクセスの利用がより効率的な処理となります。

std::string s = "abc";
if (s[0] == 'a') puts("文字`a`で始まる文字列です");

find_first_ofメンバ関数を用いることで、複数の文字のいずれかの文字で始まるかどうかを判定することもできます。

std::string s = "abc";
if (s.find_first_of("Aa") == 0) {
   puts("文字`A`または`a`で始まる文字列です");
}

starts_with関数

以下はequal関数を用いたstarts_with関数の実装例です。指定の文字列sprefixに指定された文字列/文字で始まるかどうかを判定することができます。

bool starts_with(const std::string& s, const std::string& prefix) {
   auto size = prefix.size();
   if (s.size() < size) return false;
   return std::equal(std::begin(prefix), std::end(prefix), std::begin(s));
}
assert(  starts_with("abc", "")     );
assert(  starts_with("abc", "a")    );
assert(  starts_with("abc", "ab")   );
assert(  starts_with("abc", "abc")  );
assert( !starts_with("abc", "abcd") );

広告