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

时间:2011-10-13 14:31:21

标签: c++ string stl

如果你想知道一个字符串是否以另一个字符串开头,那你将如何在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 ++等)吗?

5 个答案:

答案 0 :(得分:14)

find的缺点是如果str1很长,那么它会毫无意义地搜索str2。我从来没有注意到优化器足够聪明,只知道结果是否为0,并且在str1开始后停止搜索。

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

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

答案 1 :(得分:9)

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

除了标准内容(返回值...)之外,没有关于STL实现如何必须实现查找或比较的要求,因此它完全取决于实现。

答案 2 :(得分:8)

由于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;
}

答案 3 :(得分:2)

即使第一个字符不匹配,

find可能必须搜索整个字符串以查找匹配项,因此我建议compare,或者如@Foo Bah所述,您可以使用boost的starts_with算法。

答案 4 :(得分:1)

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