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


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

目次

スポンサーリンク

前方一致 – prefix search, starts with

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

std::string s = "abc";

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

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

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

解決策

そのため、検索開始位置と終了位置の指定が可能なcompareメンバ関数への置き換えが有効です。

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

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

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

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

検索文字列がC言語スタイルの文字列であれば、find関数に対する終了位置の指定が可能です。

const char* cstr = prefix.c_str();
if (s.size() >= strlen(cstr) &&
    s.find(cstr, 0, strlen(cstr)) == 0) {
   puts("文字列`ab`で始まる文字列です");
}

ただし、compareメンバ関数は検索文字列の大小比較を伴うため、より処理効率の高いプログラムを求める場合には、次に説明するequal関数の利用が必要となります。

starts_with関数

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

// starts_with("abc", "ab") == true
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));
}

広告

関連するオススメの記事