检查字符串是否以另一个字符串开头:find或compare

check if string starts with another string: find or compare?

本文关键字:字符串 find compare 另一个 是否 检查 开头      更新时间:2023-10-16

如果你想知道一个字符串是否以另一个字符串开头,你如何在c++/STL中做到这一点?在Java中有String.startsWith, Python也有string.startwith, STL没有直接的方法。取而代之的是std::string::findstd::string::compare。到目前为止,我使用了这两种方法,主要取决于我当前的心情:

if ( str1.compare( 0, str2.length(), str2 ) == 0 )
    do_something();
if ( str1.find(str2) == 0 )
    do_something();

当然,你也可以做str.substr(0,str2.length()) == str2,也许还有一些其他的方法可以达到同样的效果。findcompare更方便,但我看到更多的人推荐compare而不是find

但是哪一个是首选呢?是否存在性能差异?它是否依赖于实现(GCC, vc++等)?

find的缺点是,如果str1很长,那么它将毫无意义地搜索str2。我从来没有注意到一个优化器足够聪明,可以意识到你只关心结果是否为0,并在str1开始后停止搜索。

compare的缺点是您需要检查str2.length()是否大于str1.length()(或者捕获产生的异常并将其视为错误结果)。

令人失望的是,在标准库中最接近您想要的是std::strncmp(当然您需要使用c_str()),因此需要boost::starts_with或您自己的等同物,其中包括边界检查。

boost有一个算法starts_with可以相当有效地实现它:http://www.boost.org/doc/libs/1_41_0/doc/html/boost/algorithm/starts_with.html

没有关于STL实现必须如何实现查找或比较的要求,除了标准的东西(返回值…),所以它完全依赖于实现。

由于find()可能无论如何都必须搜索整个string,如果您愿意,可以像这样包装compare():

#include <iostream>
#include <string>
using namespace std;
bool starts_with(const string& s1, const string& s2) {
    return s2.size() <= s1.size() && s1.compare(0, s2.size(), s2) == 0;
}
int main() {
    const string s("zipzambam");
    cout << starts_with(s, "zip") << endl;
}

find可能不得不搜索整个字符串寻找匹配,即使第一个字符不匹配,所以我建议compare,或者正如@Foo Bah所提到的,你可以使用boost的starts_with算法。

你可以试试std::mismatch,这个算法唯一的愚蠢的的事情是你必须确保第一个范围小于或等于第二个范围