检查一个字符串是否是另一个字符串的前缀

问题描述 投票:41回答:12

我有两个字符串,我想比较一下:StringString:。是否有一个库函数在传递这两个字符串时会返回true,但是对于StringOtherString来说是假的?

确切地说,我想知道一个字符串是否是另一个字符串的前缀。

c++ string-comparison prefix
12个回答
49
投票

使用std::mismatch。传入较短的字符串作为第一个迭代器范围,将较长的字符串作为第二个迭代器范围传递。返回是一对迭代器,第一个是第一个范围中的迭代器,第二个是第二个范围内的迭代器。如果第一个是第一个范围的结尾,那么您知道短字符串是较长字符串的前缀,例如

std::string foo("foo");
std::string foobar("foobar");

auto res = std::mismatch(foo.begin(), foo.end(), foobar.begin());

if (res.first == foo.end())
{
  // foo is a prefix of foobar.
}

0
投票

如果在str1的索引0处找到整个str2,则str1.find(str2)返回0:

#include <string>
#include <iostream>

// does str1 have str2 as prefix?
bool StartsWith(const std::string& str1, const std::string& str2)
{   
    return (str1.find(str2)) ? false : true;
}

// is one of the strings prefix of the another?
bool IsOnePrefixOfAnother(const std::string& str1, const std::string& str2)
{   
    return (str1.find(str2) && str2.find(str1)) ? false : true;
}

int main()
{
    std::string str1("String");
    std::string str2("String:");
    std::string str3("OtherString");

    if(StartsWith(str2, str1))
    {
        std::cout << "str2 starts with str1" << std::endl;      
    }
    else
    {
        std::cout << "str2 does not start with str1" << std::endl;
    }

    if(StartsWith(str3, str1))
    {
        std::cout << "str3 starts with str1" << std::endl;      
    }
    else
    {
        std::cout << "str3 does not start with str1" << std::endl;
    }

        if(IsOnePrefixOfAnother(str2, str1))
        {
            std::cout << "one is prefix of another" << std::endl;      
        }
        else
        {
            std::cout << "one is not prefix of another" << std::endl;
        }

        if(IsOnePrefixOfAnother(str3, str1))
        {
            std::cout << "one is prefix of another" << std::endl;      
        }
        else
        {
            std::cout << "one is not prefix of another" << std::endl;
        }

    return 0;
}

输出:

  str2 starts with str1
  str3 does not start with str1
  one is prefix of another
  one is not prefix of another

0
投票

“查找”和检查位置0的结果有什么问题?

string a = "String";
string b = "String:";

if(b.find(a) == 0)
{
// Prefix

}
else
{
// No Prefix
}

0
投票

我认为strncmp最接近你想要的东西。

虽然,如果重新编号,你可能正在寻找strstr(s2,s1)==s2,这不一定是最高性能的方式。但你不想解决n ;-)

好吧,好吧,c ++版本将是!s1.find(s2)

好的,你可以把它变成更多的c ++,就像这样:std::mismatch(s1.begin(),s1.end(),s2.begin()).first==s1.end()


18
投票

如果您知道哪个字符串更短,则过程很简单,只需先使用std::equal和较短的字符串。如果不这样,以下内容应该起作用:

bool
unorderIsPrefix( std::string const& lhs, std::string const& rhs )
{
    return std::equal(
        lhs.begin(),
        lhs.begin() + std::min( lhs.size(), rhs.size() ),
        rhs.begin() );
}

15
投票

当且仅当std::string(X).find(Y)Y的前缀时,X为零


9
投票

使用string::compare,您应该能够写出如下内容:

bool match = (0==s1.compare(0, min(s1.length(), s2.length()), s2,0,min(s1.length(),s2.length())));

或者,如果我们不想使用length()成员函数:

bool isPrefix(string const& s1, string const&s2)
{
    const char*p = s1.c_str();
    const char*q = s2.c_str();
    while (*p&&*q)
        if (*p++!=*q++)
            return false;
    return true;
}

6
投票

这既高效又方便:

str.compare(0, pre.size(), pre) == 0

compare很快,因为它使用快速的traits::compare方法,而不必复制任何数据。

这里,它将比较std::min(str.size(), pre.size())字符,但如果两个范围中的字符相等,它还会检查pre的长度,如果pre长于此值,则返回非零值。

请参阅cplusplus.com上的the documentation


5
投票

怎么样简单:

bool prefix(const std::string& a, const std::string& b) {
  if (a.size() > b.size()) {
    return a.substr(0,b.size()) == b;
  }
  else {
    return b.substr(0,a.size()) == a;
  }
}

C ++不是C,安全,简单,高效。

经测试:

#include <string>
#include <iostream>

bool prefix(const std::string& a, const std::string& b);

int main() {
  const std::string t1 = "test";
  const std::string t2 = "testing";
  const std::string t3 = "hello";
  const std::string t4 = "hello world";
  std::cout << prefix(t1,t2) << "," << prefix(t2,t1) << std::endl;
  std::cout << prefix(t3,t4) << "," << prefix(t4,t3) << std::endl;
  std::cout << prefix(t1,t4) << "," << prefix(t4,t1) << std::endl;
  std::cout << prefix(t1,t3) << "," << prefix(t3,t1) << std::endl;

}

5
投票

如果您可以合理地忽略任何多字节编码(例如,UTF-8),那么您可以使用strncmp

// Yields true if the string 's' starts with the string 't'.
bool startsWith( const std::string &s, const std::string &t )
{
    return strncmp( s.c_str(), t.c_str(), t.size() ) == 0;
}

如果你坚持使用花哨的C ++版本,你可以使用std::equal算法(附加的好处是你的函数也适用于其他集合,而不仅仅是字符串):

// Yields true if the string 's' starts with the string 't'.
template <class T>
bool startsWith( const T &s, const T &t )
{
    return s.size() >= t.size() &&
           std::equal( t.begin(), t.end(), s.begin() );
}

3
投票

最简单的方法是使用substr()和compare()成员函数:

string str = "Foobar";
string prefix = "Foo";

if(str.substr(0, prefix.size()).compare(prefix) == 0) cout<<"Found!";

1
投票

你可以用这个:

对于c ++ 14或更低版本

bool has_prefix
    (const std::string& str, const std::string& prefix)  {
    return str.find(prefix, 0) == 0;
}

对于c ++ 17

//it's a little faster
auto has_prefix
    (const std::string& str, const std::string_view& prefix) -> decltype(str.find(prefix) == 0) {
    return str.find(prefix, 0) == 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.